before(function() use ($app) { $app['firewall']->requireAuthentication(); $app['firewall']->requireAccessToModule('thesaurus'); }); $controllers->match('acceptcandidates.j.php', $this->call('AcceptCandidatesJson')); $controllers->match('checkcandidatetarget.j.php', $this->call('CheckCandidateTargetJson')); $controllers->match('editing_presets.j.php', $this->call('EditingPresetsJson')); $controllers->match('getsy_prod.x.php', $this->call('GetSynonymsXml')); $controllers->match('getterm_prod.h.php', $this->call('GetTermHtml')); $controllers->match('getterm_prod.x.php', $this->call('GetTermXml')); $controllers->match('openbranch_prod.j.php', $this->call('OpenBranchJson')); $controllers->match('openbranches_prod.h.php', $this->call('OpenBranchesHtml')); $controllers->match('openbranches_prod.x.php', $this->call('OpenBranchesXml')); $controllers->match('replacecandidate.j.php', $this->call('ReplaceCandidateJson')); $controllers->match('search_th_term_prod.j.php', $this->call('SearchTermJson')); return $controllers; } public function AcceptCandidatesJson(Application $app, Request $request) { $ret = array('refresh' => array()); $refresh = array(); $sbas_id = $request->get('sbid'); try { $databox = $app['phraseanet.appbox']->get_databox($sbas_id); $connbas = $databox->get_connection(); $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") . "']"; } if ($request->get("debug")) { printf("qth: %s
\n", $q); } $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); $oldid = $ct->getAttribute("id"); $te = $domth->importNode($ct, true); $chgids = array(); if (($pid = $parentnode->getAttribute("id")) == "") { $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")); } $soldid = str_replace(".", "d", $oldid) . "d"; $snewid = str_replace(".", "d", $pid) . "d"; $l = strlen($soldid) + 1; $sql = "UPDATE thit SET value=CONCAT('$snewid', SUBSTRING(value FROM $l)) WHERE value LIKE :like"; if ($request->get("debug")) { printf("soldid=%s ; snewid=%s
\nsql=%s
\n", $soldid, $snewid, $sql); } else { $stmt = $connbas->prepare($sql); $stmt->execute(array(':like' => $soldid . '%')); $stmt->closeCursor(); } $refreshid = $parentnode->getAttribute('id'); $refresh['T' . $refreshid] = array( 'type' => 'T', 'sbid' => $sbas_id, 'id' => $refreshid ); $thchanged = true; $refreshid = $ct->parentNode->getAttribute("id"); $refresh['C' . $refreshid] = array( '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; } if ($request->get('debug')) { printf("ct2:%s \n", var_export($ct2, true)); } $nid = $parentnode->getAttribute("nextid"); $parentnode->setAttribute("nextid", (int) $nid + 1); $oldid = $ct2->getAttribute("id"); $te = $domth->importNode($ct2, true); $chgids = array(); 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")); } $soldid = str_replace(".", "d", $oldid) . "d"; $snewid = str_replace(".", "d", $pid) . "d"; $l = strlen($soldid) + 1; $sql = "UPDATE thit SET value = CONCAT('$snewid', SUBSTRING(value FROM $l)) WHERE value LIKE :like"; if ($request->get("debug")) { printf("soldid=%s ; snewid=%s
\nsql=%s
\n", $soldid, $snewid, $sql); } else { $stmt = $connbas->prepare($sql); $stmt->execute(array(':like' => $soldid . '%')); $stmt->closeCursor(); } $thchanged = true; } $refreshid = $parentnode->parentNode->getAttribute("id"); $refresh['T' . $refreshid] = array( 'type' => 'T', 'sbid' => $sbas_id, 'id' => $refreshid ); $refreshid = $ct->parentNode->getAttribute("id"); $refresh['C' . $refreshid] = array( '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 $app->json($ret); } private function renumerate($lang, $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(Application $app, Request $request) { $json = array(); if (null === $sbas_id = $request->get("sbid")) { return $app->json($json); } $databox = $app['phraseanet.appbox']->get_databox((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; 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 $app->json($json); } public function EditingPresetsJson(Application $app, Request $request) { $usr_id = $app['authentication']->getUser()->get_id(); $ret = array('parm' => array( 'act' => $request->get('act'), 'sbas' => $request->get('sbas'), 'presetid' => $request->get('presetid'), 'title' => $request->get('title'), 'f' => $request->get('f'), 'debug' => $request->get('debug'), )); switch ($request->get('act')) { case 'DELETE': $sql = 'DELETE FROM edit_presets WHERE edit_preset_id = :editpresetid AND usr_id = :usr_id'; $params = array( ':editpresetid' => $request->get('presetid'), ':usr_id' => $usr_id ); $stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql); $stmt->execute($params); $stmt->closeCursor(); $ret['html'] = $this->getPresetHTMLList($app, $request->get('sbas'), $usr_id); break; case 'SAVE': $dom = new \DOMDocument('1.0', 'UTF-8'); $dom->standalone = true; $dom->preserveWhiteSpace = false; $dom->formatOutput = true; $xml = '' . $request->get('f') . ''; $dom->loadXML($xml); $sql = 'INSERT INTO edit_presets (creation_date, sbas_id, usr_id, title, xml) VALUES (NOW(), :sbas_id, :usr_id, :title, :presets)'; $params = array( ':sbas_id' => $request->get('sbas'), ':usr_id' => $usr_id, ':title' => $request->get('title'), ':presets' => $dom->saveXML(), ); $stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql); $stmt->execute($params); $stmt->closeCursor(); $ret['html'] = $this->getPresetHTMLList($app, $request->get('sbas'), $usr_id); break; case 'LIST': $ret['html'] = $this->getPresetHTMLList($app, $request->get('sbas'), $usr_id); break; case "LOAD": $sql = 'SELECT edit_preset_id, creation_date, title, xml FROM edit_presets WHERE edit_preset_id = :edit_preset_id'; $stmt = $app['phraseanet.appbox']->get_connection()->prepare($sql); $stmt->execute(array(':edit_preset_id' => $request->get('presetid'))); $row = $stmt->fetch(\PDO::FETCH_ASSOC); $stmt->closeCursor(); $fields = array(); if ($row && ($sx = simplexml_load_string($row['xml']))) { foreach ($sx->fields->children() as $fn => $fv) { if (!array_key_exists($fn, $fields)) { $fields[$fn] = array(); } $fields[$fn][] = trim($fv); } } $ret['fields'] = $fields; break; } return $app->json($ret); } private function getPresetHTMLList(Application $app, $sbas_id, $usr_id) { $conn = \connection::getPDOConnection($app); $html = ''; $sql = 'SELECT edit_preset_id, creation_date, title, xml FROM edit_presets WHERE usr_id = :usr_id AND sbas_id = :sbas_id ORDER BY creation_date ASC'; $stmt = $conn->prepare($sql); $stmt->execute(array( ':sbas_id' => $sbas_id, ':usr_id' => $usr_id, )); $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); $stmt->closeCursor(); foreach ($rs as $row) { if (!($sx = simplexml_load_string($row['xml']))) { continue; } $t_desc = array(); foreach ($sx->fields->children() as $fn => $fv) { if (!array_key_exists($fn, $t_desc)) { $t_desc[$fn] = trim($fv); } else { $t_desc[$fn] .= ' ; ' . trim($fv); } } $desc = ''; foreach ($t_desc as $fn => $fv) { $desc .= '

' . $fn . ': ' . str_replace(array('&', '<', '>'), array('&', '<', '>'), $fv) . '

' . "\n"; } ob_start(); ?>
  • standalone = true; $ret->preserveWhiteSpace = false; $root = $ret->appendChild($ret->createElement("result")); $root->appendChild($ret->createCDATASection(var_export(array( 'bid' => $request->get('bid'), 'id' => $request->get('id'), ), true))); if (null !== $request->get('bid')) { $databox = $app['phraseanet.appbox']->get_databox((int) $request->get('bid')); $dom = $databox->get_dom_thesaurus(); if ($dom) { $xpath = $databox->get_xpath_thesaurus(); $q = "/thesaurus//sy[@id='" . $request->get('id') . "']"; if ($request->get('debug')) { print("q:" . $q . "
    \n"); } $nodes = $xpath->query($q); if ($nodes->length > 0) { $n2 = $nodes->item(0); $root->setAttribute("t", $n2->getAttribute("v")); } } } return new Response($ret->saveXML(), 200, array('Content-Type' => 'text/xml')); } public function GetTermHtml(Application $app, Request $request) { $html = ''; if (null === $request->get("bid")) { return new Response('Missing bid parameter', 400); } $databox = $app['phraseanet.appbox']->get_databox((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 = array(); // on dresse la liste des termes specifiques avec comme cle le synonyme // dans la langue pivot for ($n = $nodes->item(0)->firstChild; $n; $n = $n->nextSibling) { if ($n->nodeName == "te") { $nts++; $allsy = ""; $tsy = array(); $firstksy = null; $ksy = $realksy = null; // on liste les sy pour fabriquer la cle 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")) { // $t .= " ($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, array( "id" => $n2->getAttribute("id"), "sy" => $t )); } else { $allsy .= ( $allsy ? " ; " : "") . $t; array_push($tsy, array( "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] = array( "id" => $n->getAttribute("id"), "allsy" => $allsy, "nchild" => $xpath->query("te", $n)->length, "tsy" => $tsy ); } else { $tts[] = array( "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"]; $t = $ts["allsy"]; $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(Application $app, Request $request) { $ret = new \DOMDocument("1.0", "UTF-8"); $ret->standalone = true; $ret->preserveWhiteSpace = false; $root = $ret->appendChild($ret->createElement("result")); $root->appendChild($ret->createCDATASection(var_export(array( "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 = $app['phraseanet.appbox']->get_databox((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 = array(); // on dresse la liste des termes specifiques avec comme cle le synonyme // dans la langue pivot for ($n = $nodes->item(0)->firstChild; $n; $n = $n->nextSibling) { if ($n->nodeName == "te") { $nts++; $allsy = ""; $tsy = array(); $firstksy = null; $ksy = $realksy = null; // on liste les sy pour fabriquer la cle 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 && $app['locale'] && $lng == $app['locale']) { $realksy = $ksy; $allsy = $t . ($allsy ? " ; " : "") . $allsy; array_push($tsy, array( "id" => $n2->getAttribute("id"), "sy" => $t )); } else { $allsy .= ( $allsy ? " ; " : "") . $t; array_push($tsy, array( "id" => $n2->getAttribute("id"), "sy" => $t )); } } } if (!$realksy) $realksy = $firstksy; if ($request->get("sortsy") && $app['locale']) { for ($uniq = 0; $uniq < 9999; $uniq++) { if (!isset($tts[$realksy . "_" . $uniq])) { break; } } $tts[$realksy . "_" . $uniq] = array( "id" => $n->getAttribute("id"), "allsy" => $allsy, "nchild" => $xpath->query("te", $n)->length, "tsy" => $tsy ); } else { $tts[] = array( "id" => $n->getAttribute("id"), "allsy" => $allsy, "nchild" => $xpath->query("te", $n)->length, "tsy" => $tsy ); } } elseif ($n->nodeName == "sy") { } } if ($request->get("sortsy") && $app['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, array('Content-Type' => 'text/xml')); } public function OpenBranchJson(Application $app, Request $request) { if (null === $lng = $request->get('lng')) { $data = explode('_', $app['locale']); if (count($data) > 0) { $lng = $data[0]; } } $html = ''; $sbid = (int) $request->get('sbid'); $tids = explode('.', $request->get('id')); $thid = implode('.', $tids); try { $connbas = \connection::getPDOConnection($app, $sbid); $dbname = \phrasea::sbas_names($sbid, $app); $t_nrec = array(); $lthid = strlen($thid); // count occurences if ($lthid == 1) { $dthid = str_replace('.', 'd', $thid); $sql = 'SELECT COUNT(DISTINCT record_id) AS n FROM thit WHERE value LIKE :like '; $stmt = $connbas->prepare($sql); $stmt->execute(array(':like' => $dthid . '%')); $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); $stmt->closeCursor(); if ($request->get('debug')) { printf("/*\n thid=%s\n %s \n */\n", $thid, $sql); } foreach ($rs as $rowbas) { $t_nrec[$thid] = $rowbas; } $sql = 'SELECT SUBSTRING_INDEX(SUBSTR(value, ' . ($lthid + 1) . '), "d", 1) AS k , COUNT(DISTINCT record_id) AS n FROM thit WHERE value LIKE :like GROUP BY k'; $stmt = $connbas->prepare($sql); $stmt->execute(array(':like' => $dthid . '%')); $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); $stmt->closeCursor(); if ($request->get('debug')) { printf("/*\n thid=%s\n %s \n */\n", $thid, $sql); } foreach ($rs as $rowbas) { $t_nrec[$thid . $rowbas['k']] = $rowbas; } } elseif (strlen($thid) > 1) { $dthid = str_replace('.', 'd', $thid); $sql = 'SELECT SUBSTRING_INDEX(SUBSTR(value, ' . ($lthid) . '), \'d\', 1) AS k , COUNT(DISTINCT record_id) AS n FROM thit WHERE value LIKE :like GROUP BY k'; $stmt = $connbas->prepare($sql); $stmt->execute(array(':like' => $dthid . '%')); $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); $stmt->closeCursor(); if ($request->get('debug')) { printf("/*\n thid=%s\n %s \n */\n", $thid, $sql); } foreach ($rs as $rowbas) { $t_nrec[$thid] = $rowbas; } $sql = 'SELECT SUBSTRING_INDEX(SUBSTR(value, ' . ($lthid + 2) . '), \'d\', 1) AS k , COUNT(DISTINCT record_id) AS n FROM thit WHERE value LIKE :like GROUP BY k'; $stmt = $connbas->prepare($sql); $stmt->execute(array(':like' => $dthid . '%')); $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); $stmt->closeCursor(); if ($request->get('debug')) { printf("/*\n thid=%s\n %s \n */\n", $thid, $sql); } foreach ($rs as $rowbas) { $t_nrec[$thid . '.' . $rowbas['k']] = $rowbas; } } if ($request->get('debug')) { printf("/* %s */\n", var_export($t_nrec, true)); } $databox = $app['phraseanet.appbox']->get_databox($sbid); if ($request->get('type') == 'T') { $xqroot = 'thesaurus'; $dom = $databox->get_dom_thesaurus(); } else { // C $xqroot = 'cterms'; $dom = $databox->get_dom_cterms(); } if ($dom) { $term0 = ''; $firstTerm0 = ''; $xpath = new \DOMXPath($dom); if ($thid == 'T' || $thid == 'C') { $q = '/' . $xqroot; $term0 = $dbname; } else { $q = '/' . $xqroot . '//te[@id=\'' . $thid . '\']'; } if ($request->get('debug')) { print("q:" . $q . "
    \n"); } $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) $nts0 = 0; // count of ts under this term $label = $this->buildBranchLabel($dbname, $lng, $node0, $key0, $nts0); $class = ''; if ($nts0 > 0) { $class .= ( $class == '' ? '' : ' ') . 'expandable'; } if ($request->get('last')) { $class .= ( $class == '' ? '' : ' ') . 'last'; } $html .= '
  • ' . "\n"; $html .= '
    ' . "\n"; $html .= ' ' . $label . ''; if (isset($t_nrec[$thid])) { $html .= ' ' . $t_nrec[$thid]['n'] . ''; } $html .= "\n"; // on dresse la liste des termes specifiques avec comme cle le synonyme dans la langue pivot $nts = 0; $tts = array(); for ($n = $node0->firstChild; $n; $n = $n->nextSibling) { if ($n->nodeName == 'te' && !$n->getAttribute('delbranch')) { $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] = array( 'label' => $label, 'nts' => $nts0, 'n' => $n ); } } if ($request->get('debug')) { printf("tts(%s) :
    %s

    \n", $nts, var_export($tts, true)); } if ($nts > 0) { $field0 = $node0->getAttribute('field'); if ($field0) { $field0 = 'field="' . $field0 . '"'; } $html .= '' . "\n"; } $html .= '
  • ' . "\n"; } } } catch (\Exception $e) { } return $app->json(array('parm' => array( '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, $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(Application $app, 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 = $app['phraseanet.appbox']->get_databox((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 ($request->get('debug')) { print('q:' . $q . '
    \n'); } if (($znode = $xpath->query($q)->item(0))) { $q2 = '//sy'; if ($request->get('t')) { $t = $this->splitTermAndContext($request->get('t')); $q2 = 'starts-with(@w, \'' . \thesaurus::xquery_escape($app['unicode']->remove_indexer_chars($t[0])) . '\')'; if ($t[1]) { $q2 .= ' and starts-with(@k, \'' . \thesaurus::xquery_escape($app['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 .= '

    '; } } if ($request->get('debug')) { printf('zhtml=%s
    \n', $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 array($term, $context); } private function getBranchesHTML($bid, $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 OpenBranchesXml(Application $app, Request $request) { if (null === $mod = $request->get('mod')) { $mod = 'TREE'; } $ret = new \DOMDocument('1.0', 'UTF-8'); $ret->standalone = true; $ret->preserveWhiteSpace = false; $root = $ret->appendChild($ret->createElement('result')); $root->appendChild($ret->createCDATASection(var_export(array( '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); } $databox = $app['phraseanet.appbox']->get_databox((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 ($request->get('debug')) { print('q:' . $q . '
    \n'); } if (($znode = $xpath->query($q)->item(0))) { $q2 = '//sy'; if ($request->get('t')) { $t = $this->splitTermAndContext($request->get('t')); $q2 = 'starts-with(@w, \'' . \thesaurus::xquery_escape($app['unicode']->remove_indexer_chars($t[0])) . '\')'; if ($t[1]) $q2 .= ' and starts-with(@k, \'' . \thesaurus::xquery_escape($app['unicode']->remove_indexer_chars($t[1])) . '\')'; $q2 = '//sy[' . $q2 . ']'; } if ($request->get('debug')) { print('q2:' . $q2 . '
    \n'); } $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'); if ($request->get('debug')) { printf('opening node te id=%s
    \n', $n->getAttribute('id')); } } } $zhtml = ''; $this->getBrancheXML($bid, $znode, $zhtml, 0); } else { $zhtml = ''; for ($i = 0; $i < $nodes->length; $i++) { $n = $nodes->item($i); $t = $n->getAttribute('v'); $tid = $n->getAttribute('id'); $zhtml .= '

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

    '; } } if ($request->get('debug')) { printf('zhtml=%s
    \n', $zhtml); } $html->appendChild($ret->createTextNode($zhtml)); } return new Response($zhtml, 200, array('Content-Type' => 'text/xml')); } private function getBrancheXML($bid, $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(Application $app, Request $request) { $tsbas = array(); $ret = array( 'ctermsDeleted' => array(), '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] = array( 'sbas_id' => (int) $sbas_id, 'tids' => array(), 'domct' => null, 'tvals' => array(), 'lid' => '', 'trids' => array() ); } $tsbas['b' . $sbas_id]['tids'][] = implode('.', $id); } if ($request->get('debug')) { var_dump($tsbas); } $appbox = $app['phraseanet.appbox']; // first, count the number of records to update foreach ($tsbas as $ksbas => $sbas) { /* @var $databox databox */ try { $databox = $appbox->get_databox($sbas['sbas_id']); $connbas = $databox->get_connection(); // $domth = $databox->get_dom_thesaurus(); $tsbas[$ksbas]['domct'] = $databox->get_dom_cterms(); } catch (\Exception $e) { continue; } if (!$tsbas[$ksbas]['domct']) { continue; } $lid = ''; $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 = $term = $nodes->item(0); $syid = str_replace('.', 'd', $sy->getAttribute('id')) . 'd'; $lid .= ( $lid ? ',' : '') . "'" . $syid . "'"; $field = $sy->parentNode->parentNode->getAttribute('field'); if (!array_key_exists($field, $tsbas[$ksbas]['tvals'])) { $tsbas[$ksbas]['tvals'][$field] = array(); } $tsbas[$ksbas]['tvals'][$field][] = $sy; } } if ($lid == '') { // no cterm was found continue; } $tsbas[$ksbas]['lid'] = $lid; // count records $sql = 'SELECT DISTINCT record_id AS r FROM thit WHERE value IN (' . $lid . ') ORDER BY record_id'; $stmt = $connbas->prepare($sql); $stmt->execute(); if ($request->get('debug')) { printf("(%d) sql: \n", __LINE__); var_dump($sql); } $tsbas[$ksbas]['trids'] = $stmt->fetchAll(\PDO::FETCH_COLUMN, 0); $stmt->closeCursor(); $ret['nRecsToUpdate'] += count($tsbas[$ksbas]['trids']); } if ($request->get('debug')) { printf("(%d) nRecsToUpdate = %d \ntsbas: \n", __LINE__, $ret['nRecsToUpdate']); print_r($tsbas); } if ($ret['nRecsToUpdate'] <= self::SEARCH_REPLACE_MAXREC) { foreach ($tsbas as $sbas) { /* @var $databox databox */ try { $databox = $appbox->get_databox($sbas['sbas_id']); $connbas = $databox->get_connection(); } catch (\Exception $e) { continue; } // fix caption of records foreach ($sbas['trids'] as $rid) { if ($request->get('debug')) { printf("(%d) ======== working on record_id = %d ======= \n", __LINE__, $rid); } try { $record = $databox->get_record($rid); $metadatask = array(); // datas to keep $metadatasd = array(); // 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(); if ($request->get('debug')) { printf("(%d) field '%s' meta_struct_id=%s \n", __LINE__, $field->get_name(), $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) { if ($request->get('debug')) { printf("(%d) ...v = '%s' (meta_id=%s) keep \n", __LINE__, $v->getValue(), $v->getId()); } $metadatask[] = array( 'meta_struct_id' => $meta_struct_id, 'meta_id' => $v->getId(), 'value' => $v->getValue() ); } } else { foreach ($field->get_values() as $v) { $keep = true; $vtxt = $app['unicode']->remove_indexer_chars($v->getValue()); foreach ($sbas['tvals'][$fname] as $sy) { if ($sy->getAttribute('w') == $vtxt) { $keep = false; } } if ($request->get('debug')) { printf("(%d) ...v = '%s' (meta_id=%s) %s \n", __LINE__, $v->getValue(), $v->getId(), ($keep ? '' : '!!! drop !!!')); } if ($keep) { $metadatask[] = array( 'meta_struct_id' => $meta_struct_id, 'meta_id' => $v->getId(), 'value' => $v->getValue() ); } else { $metadatasd[] = array( 'meta_struct_id' => $meta_struct_id, 'meta_id' => $v->getId(), 'value' => $request->get('t') ? $request->get('t') : '' ); } } } } if ($request->get('debug')) { printf("(%d) metadatask: \n", __LINE__); var_dump($metadatask); printf("(%d) metadatasd: \n", __LINE__); var_dump($metadatasd); } if (count($metadatasd) > 0) { if (!$request->get('debug')) { $record->set_metadatas($metadatasd, true); $ret['nRecsUpdated']++; } } } catch (\Exception $e) { continue; } } // delete the branch from the cterms if ($request->get('debug')) { printf("cterms before :\n%s \n", $sbas['domct']->saveXML()); } 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')) { printf("cterms after :\n%s \n", $sbas['domct']->saveXML()); } if (!$request->get('debug')) { $databox->saveCterms($sbas['domct']); } } $ret['msg'] = sprintf(_('prod::thesaurusTab:dlg:%d record(s) updated'), $ret['nRecsUpdated']); } else { // too many records to update $ret['msg'] = sprintf(_('prod::thesaurusTab:dlg:too many (%1$d) records to update (limit=%2$d)'), $ret['nRecsToUpdate'], self::SEARCH_REPLACE_MAXREC); } return $app->json($ret); } public function SearchTermJson(Application $app, Request $request) { if (null === $lng = $request->get('lng')) { $data = explode('_', $app['locale']); if (count($data) > 0) { $lng = $data[0]; } } $html = ''; $sbid = (int) $request->get('sbid'); $dbname = ''; try { $databox = $app['phraseanet.appbox']->get_databox($sbid); $html = "" . '' . "\n"; } catch (\Exception $e) { } return $app->json(array('parm' => array( 'sbid' => $request->get('sbid'), 't' => $request->get('t'), 'field' => $request->get('field'), 'lng' => $request->get('lng'), 'debug' => $request->get('debug'), ), 'html' => $html)); } private function buildTermLabel($language, $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; } private function getHTMLTerm($sbid, $lng, $srcnode, &$html, $depth = 0) { $tid = $srcnode->getAttribute('id'); // let's work on each 'te' (=ts) subnode $nts = 0; $ntsopened = 0; $tts = array(); 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 $label = $this->buildTermLabel($lng, $n, $key0, $nts0); for ($uniq = 0; $uniq < 9999; $uniq++) { if (!isset($tts[$key0 . '_' . $uniq])) break; } $tts[$key0 . '_' . $uniq] = array('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 { $html .= $tab . '' . "\n"; } } } private function call($method) { return sprintf('%s::%s', __CLASS__, $method); } }