From 694033b9094026a97b98e9b18168ef353603b35a Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Wed, 31 Oct 2012 09:55:22 +0100 Subject: [PATCH 01/22] Fix #985 : Thesaurus bouncing --- lib/classes/caption/record.class.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/classes/caption/record.class.php b/lib/classes/caption/record.class.php index 0b08ed8ad8..4adf68e35d 100644 --- a/lib/classes/caption/record.class.php +++ b/lib/classes/caption/record.class.php @@ -267,16 +267,21 @@ class caption_record implements caption_interface, cache_cacheableInterface $ret = $searchEngine->build_excerpt($highlight, $fields, $this->record); if ($ret) { - $n = 0; + $n = -1; foreach ($fields as $key => $value) { - if ( ! isset($fields[$key])) + $n++; + + if (!isset($fields[$key])) { continue; + } + + if (strpos($fields[$key]['value'], ' Date: Wed, 31 Oct 2012 10:42:51 +0100 Subject: [PATCH 02/22] fix #976 edit : character change when editing with thesaurus fix also display caption junk when a thesaurus term has no entry in the current language --- lib/classes/caption/Field/Value.class.php | 2 +- www/prod/jquery.edit.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/classes/caption/Field/Value.class.php b/lib/classes/caption/Field/Value.class.php index 604bdb739b..69dcf9d79a 100644 --- a/lib/classes/caption/Field/Value.class.php +++ b/lib/classes/caption/Field/Value.class.php @@ -470,7 +470,7 @@ class caption_Field_Value implements cache_cacheableInterface break; } - $synonyms = $XPATH_thesaurus->query("sy[@lng='" . $session->usr_i18 . "']", $node->parentNode); + $synonyms = $XPATH_thesaurus->query("sy[@lng='" . $session->get_I18n() . "']", $node->parentNode); foreach ($synonyms as $synonym) { $k = $synonym->getAttribute("k"); if ($synonym->getAttribute("w") != $term_noacc || $k != $context_noacc) { diff --git a/www/prod/jquery.edit.js b/www/prod/jquery.edit.js index 96866d0fac..ee3da94e3f 100644 --- a/www/prod/jquery.edit.js +++ b/www/prod/jquery.edit.js @@ -417,7 +417,7 @@ function updateCurrentMval(meta_struct_id, HighlightValue, vocabularyId) + ' +
' + extra + '' - + word + + $('
').text(word).html() + "
" + ' ' + '' @@ -1288,7 +1288,7 @@ function edit_dblclickThesaurus(event) // ondblclick dans le thesaurus case "TH_W": if(p4.edit.curField >= 0) { - var w = e.innerHTML; + var w = $(e).text(); if(p4.edit.T_fields[p4.edit.curField].multi) { $("#EditTextMultiValued", p4.edit.editBox).val(w); From c1f8f0bb8ab863b193f2135ef8163de1b0984b46 Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Mon, 5 Nov 2012 14:42:49 +0100 Subject: [PATCH 03/22] Fix #983 : Fix download of basket containing slash in their titles --- lib/classes/record/exportElement.class.php | 6 ++++++ lib/classes/set/export.class.php | 4 ++-- www/include/download.php | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/classes/record/exportElement.class.php b/lib/classes/record/exportElement.class.php index 593b25bdbd..c13a03d4d3 100644 --- a/lib/classes/record/exportElement.class.php +++ b/lib/classes/record/exportElement.class.php @@ -58,6 +58,12 @@ class record_exportElement extends record_adapter public function __construct($sbas_id, $record_id, $directory = '', $remain_hd = false) { $this->directory = $directory; + + if ($this->directory) { + $unicode = new \unicode(); + $this->directory = $unicode->remove_nonazAZ09($this->directory) . '/'; + } + $this->remain_hd = $remain_hd; $this->size = array(); parent::__construct($sbas_id, $record_id); diff --git a/lib/classes/set/export.class.php b/lib/classes/set/export.class.php index 558555073c..8869ef62c0 100644 --- a/lib/classes/set/export.class.php +++ b/lib/classes/set/export.class.php @@ -82,7 +82,7 @@ class set_export extends set_abstract new record_exportElement( $basket_element->getRecord()->get_sbas_id(), $record_id, - $Basket->getName() . '/', + $Basket->getName(), $remain_hd[$base_id] ); @@ -120,7 +120,7 @@ class set_export extends set_abstract new record_exportElement( $child_basrec->get_sbas_id(), $record_id, - $record->get_title(null, null, true) . '_' . $n . '/', + $record->get_title(null, null, true) . '_' . $n, $remain_hd[$base_id] ); diff --git a/www/include/download.php b/www/include/download.php index fa7e7a4a5a..f04de023f8 100644 --- a/www/include/download.php +++ b/www/include/download.php @@ -47,7 +47,7 @@ if ($parm["ssttid"] != "") { /* @var $repository \Repositories\BasketRepository */ $basket = $repository->findUserBasket($Request->get('ssttid'), $Core->getAuthenticatedUser(), false); - $exportname = str_replace(' ', '_', $basket->getName()) . "_" . date("Y-n-d"); + $exportname = str_replace(array(' ', '\\', '/'), '_', $basket->getName()) . "_" . date("Y-n-d"); } $list['export_name'] = $exportname . '.zip'; From 681ad3224ab5c69f122af5e44c0ff8b2db0ca559 Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Mon, 5 Nov 2012 14:52:31 +0100 Subject: [PATCH 04/22] Fix #991 : add filename extension for document-class subdefs differents than document --- lib/classes/set/export.class.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/classes/set/export.class.php b/lib/classes/set/export.class.php index 8869ef62c0..511ed5be99 100644 --- a/lib/classes/set/export.class.php +++ b/lib/classes/set/export.class.php @@ -555,8 +555,7 @@ class set_export extends set_abstract $infos = pathinfo(p4string::addEndSlash($tmp_pathfile["path"]) . $tmp_pathfile["file"]); - $files[$id]["subdefs"][$name]["ajout"] = - $properties['class'] == 'document' ? '' : "_" . $name; + $files[$id]["subdefs"][$name]["ajout"] = $name == 'document' ? '' : "_" . $name; $files[$id]["subdefs"][$name]["path"] = $tmp_pathfile["path"]; $files[$id]["subdefs"][$name]["file"] = $tmp_pathfile["file"]; $files[$id]["subdefs"][$name]["label"] = $properties['label']; From 8496d393e7f205889aa5c440649931c3e08662d2 Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Mon, 5 Nov 2012 15:16:33 +0100 Subject: [PATCH 05/22] Fix #990 : add check on posix support for pcntl --- lib/classes/setup.class.php | 5 +++-- lib/classes/task/Scheduler.class.php | 3 +-- lib/classes/task/manager.class.php | 10 ++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/classes/setup.class.php b/lib/classes/setup.class.php index 55691183e2..0a531217cc 100644 --- a/lib/classes/setup.class.php +++ b/lib/classes/setup.class.php @@ -37,6 +37,7 @@ class setup , 'pcntl' , "PDO" , "phrasea2" + , 'posix' , "SimpleXML" , "sockets" , "xml" @@ -572,13 +573,13 @@ class setup $constraints = array(); foreach (self::$PHP_EXT as $ext) { - if ('pcntl' === $ext && 0 === stripos(strtolower(PHP_OS), 'win')) { + if (in_array($ext, array('pcntl', 'posix')) && defined('PHP_WINDOWS_VERSION_BUILD')) { continue; } if (extension_loaded($ext) !== true) { $blocker = true; - if (in_array($ext, array('ftp', 'twig', 'gmagick', 'imagick', 'pcntl'))) { + if (in_array($ext, array('ftp', 'twig', 'gmagick', 'imagick', 'pcntl', 'posix'))) { $blocker = false; } diff --git a/lib/classes/task/Scheduler.class.php b/lib/classes/task/Scheduler.class.php index f464724e16..03d85ca820 100755 --- a/lib/classes/task/Scheduler.class.php +++ b/lib/classes/task/Scheduler.class.php @@ -71,10 +71,9 @@ class task_Scheduler $nullfile = 'NUL'; } - if (function_exists('pcntl_fork')) { + if (\task_manager::isPosixPcntlSupported()) { // avoid php when a task ends pcntl_signal(SIGCHLD, SIG_IGN); - $this->method = self::METHOD_FORK; } diff --git a/lib/classes/task/manager.class.php b/lib/classes/task/manager.class.php index 6f4d7e4505..e127b92f78 100755 --- a/lib/classes/task/manager.class.php +++ b/lib/classes/task/manager.class.php @@ -156,6 +156,16 @@ class task_manager return $ret; } + /** + * Returns true if Pcntl posix supported is enabled, false otherwise + * + * @return Boolean + */ + public static function isPosixPcntlSupported() + { + return extension_loaded('pcntl') && extension_loaded('posix'); + } + public static function getAvailableTasks() { $registry = registry::get_instance(); From c3309dd2c2c9620f7660391e833330c88b55be80 Mon Sep 17 00:00:00 2001 From: jygaulier Date: Wed, 24 Oct 2012 17:02:15 +0200 Subject: [PATCH 06/22] wip : thesaurus in prod --- templates/web/prod/thesaurus.js | 4 +- www/xmlhttp/deletecandidates.j.php | 291 +++++++++++++++++++---------- www/xmlhttp/replacecandidate.j.php | 247 ++++++++++++------------ 3 files changed, 318 insertions(+), 224 deletions(-) diff --git a/templates/web/prod/thesaurus.js b/templates/web/prod/thesaurus.js index 0b73fc30e8..01aba83703 100644 --- a/templates/web/prod/thesaurus.js +++ b/templates/web/prod/thesaurus.js @@ -1290,7 +1290,7 @@ function startThesaurus(){ {% endfor %} { label:'{% trans 'prod::thesaurusTab:cmenu:Remplacer par...' %}', - disabled:true, +// disabled:true, onclick:function(menuItem, menu) { C_MenuOption(menuItem, menu, 'REPLACE', null); @@ -1298,7 +1298,7 @@ function startThesaurus(){ }, { label:'{% trans 'boutton::supprimer' %}', - disabled:true, +// disabled:true, onclick:function(menuItem, menu) { C_MenuOption(menuItem, menu, 'DELETE', null); diff --git a/www/xmlhttp/deletecandidates.j.php b/www/xmlhttp/deletecandidates.j.php index 3143e5d8ea..86ad000fea 100644 --- a/www/xmlhttp/deletecandidates.j.php +++ b/www/xmlhttp/deletecandidates.j.php @@ -15,146 +15,239 @@ * @link www.phraseanet.com */ require_once __DIR__ . "/../../lib/bootstrap.php"; -$registry = registry::get_instance(); $request = http_request::getInstance(); $parm = $request->get_parms( - 'id' + 'id', 'debug' ); +phrasea::headers(200, true, 'application/json', 'UTF-8', false); + +define('SEARCH_REPLACE_MAXREC', 25); + $tsbas = array(); -$ret = array(); - -$conn = connection::getPDOConnection(); -$unicode = new unicode(); - -$sql = "SELECT * FROM sbas"; -$stmt = $conn->prepare($sql); -$stmt->execute(); -$rs = $stmt->fetchAll(PDO::FETCH_ASSOC); -$stmt->closeCursor(); - -foreach ($rs as $row) { - $tsbas['b' . $row['sbas_id']] = array('sbas' => $row, 'tids' => array()); -} +$ret = array( + 'maxRecsUpdatable'=>SEARCH_REPLACE_MAXREC, + 'nRecsToUpdate'=>0, + 'nRecsUpdated'=>0, + 'msg'=>'' +); foreach ($parm['id'] as $id) { $id = explode('.', $id); - $sbas = array_shift($id); - if (array_key_exists('b' . $sbas, $tsbas)) - $tsbas['b' . $sbas]['tids'][] = implode('.', $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); } -foreach ($tsbas as $sbas) { - if (count($sbas['tids']) <= 0) - continue; +if ($parm['debug']) { + var_dump($tsbas); +} - $databox = databox::get_instance((int) $sbas['sbas']['sbas_id']); +$appbox = \appbox::get_instance(\bootstrap::getCore()); + + +// first, count the number of records to update +foreach ($tsbas as $ksbas=>$sbas) { + + /* @var $databox databox */ try { - $connbas = connection::getPDOConnection($sbas['sbas']['sbas_id']); + $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; } - $domth = $databox->get_dom_thesaurus(); - $domct = $databox->get_dom_cterms(); - - if ( ! $domth || ! $domct) + if ( ! $tsbas[$ksbas]['domct']) { continue; + } $lid = ''; - $tsyid = array(); - $xpathct = new DOMXPath($domct); + $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); - $w = $sy->getAttribute('w'); $syid = str_replace('.', 'd', $sy->getAttribute('id')) . 'd'; $lid .= ( $lid ? ',' : '') . "'" . $syid . "'"; - $tsyid[$syid] = array('w' => $w, 'field' => $sy->parentNode->parentNode->getAttribute('field')); + $field = $sy->parentNode->parentNode->getAttribute('field'); - // remove candidate from cterms - $te = $sy->parentNode; - $te->parentNode->removeChild($te); + if ( ! array_key_exists($field, $tsbas[$ksbas]['tvals'])) { + $tsbas[$ksbas]['tvals'][$field] = array(); + } + $tsbas[$ksbas]['tvals'][$field][] = $sy; } } - $databox->saveCterms($domct); + if ($lid == '') { + // no cterm was found + continue; + } + $tsbas[$ksbas]['lid'] = $lid; - $sql = 'SELECT t.record_id, r.xml, t.value - FROM thit AS t - INNER JOIN record AS r USING(record_id) - WHERE value IN (' . $lid . ') ORDER BY record_id'; + // 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(); - $rs = $stmt->fetchAll(PDO::FETCH_ASSOC); + + if ($parm['debug']) { + printf("(%d) sql: \n", __LINE__); + var_dump($sql); + } + + $tsbas[$ksbas]['trids'] = $stmt->fetchAll(PDO::FETCH_COLUMN, 0); $stmt->closeCursor(); - $t_rid = array(); - foreach ($rs as $rowbas) { - $rid = $rowbas['record_id']; - if ( ! array_key_exists('' . $rid, $t_rid)) - $t_rid['' . $rid] = array('xml' => $rowbas['xml'], 'hits' => array()); - $t_rid['' . $rid]['hits'][] = $rowbas['value']; - } - - foreach ($t_rid as $rid => $record) { - $dom = new DOMDocument(); - $dom->preserveWhiteSpace = false; - $dom->formatOutput = true; - if ( ! ($dom->loadXML($record['xml']))) - continue; - $nodetodel = array(); - $xp = new DOMXPath($dom); - foreach ($record['hits'] as $value) { - $field = $tsyid[$value]; - $x = '/record/description/' . $field['field']; - $nodes = $xp->query($x); - foreach ($nodes as $n) { - $current_value = $unicode->remove_indexer_chars($n->textContent); - - if ($current_value == $field['w']) { - $nodetodel[] = $n; - } - } - } - foreach ($nodetodel as $n) { - $n->parentNode->removeChild($n); - } - - $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(); - } + $ret['nRecsToUpdate'] += count($tsbas[$ksbas]['trids']); } -$ret = $parm['id']; + +if ($parm['debug']) { + printf("(%d) nRecsToUpdate = %d \ntsbas: \n", __LINE__, $ret['nRecsToUpdate']); + print_r($tsbas); +} + + +if($ret['nRecsToUpdate'] < SEARCH_REPLACE_MAXREC) +{ + $unicode = new unicode; + foreach ($tsbas as $sbas) { + + /* @var $databox databox */ + try { + $databox = $appbox->get_databox($sbas['sbas_id']); + $connbas = $databox->get_connection(); + } catch (Exception $e) { + continue; + } + + // delete the branch from the cterms + if ($parm['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); + } + } + if ($parm['debug']) { + printf("cterms after :\n%s \n", $sbas['domct']->saveXML()); + } + if ( ! $parm['debug']) { + $databox->saveCterms($sbas['domct']); + } + + // fix caption of records + foreach ($sbas['trids'] as $rid) { + + if ($parm['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 ($parm['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 ($parm['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 = $unicode->remove_indexer_chars($v->getValue()); + foreach($sbas['tvals'][$fname] as $sy) { + if ($sy->getAttribute('w') == $vtxt) { + $keep = false; + } + } + + if ($parm['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' => '' + ); + } + } + } + } + + if ($parm['debug']) { + printf("(%d) metadatas: \n", __LINE__); + var_dump($metadatasd); + } + + if(count($metadatasd) > 0) { + if ( ! $parm['debug']) { +// foreach (array('idx', 'prop', 'thit') as $t) { +// $sql = 'DELETE FROM ' . $t . ' WHERE record_id = :record_id'; +// $stmt = $connbas->prepare($sql); +// $stmt->execute(array(':record_id' => $rid)); +// $stmt->closeCursor(); +// } + $record->set_metadatas($metadatasd, true); + $ret['nRecsUpdated']++; + } + } + } catch (\Exception $e) { + continue; + } + } + } +} +else { + // too many records to update + $ret['msg'] = 'too many records to update'; +} + + /** * @todo respecter les droits d'editing par collections */ -phrasea::headers(200, true, 'application/json', 'UTF-8', false); print(p4string::jsonencode($ret)); diff --git a/www/xmlhttp/replacecandidate.j.php b/www/xmlhttp/replacecandidate.j.php index c3ff48da79..c851c904f5 100644 --- a/www/xmlhttp/replacecandidate.j.php +++ b/www/xmlhttp/replacecandidate.j.php @@ -15,7 +15,6 @@ * @link www.phraseanet.com */ require_once __DIR__ . "/../../lib/bootstrap.php"; -$registry = registry::get_instance(); $request = http_request::getInstance(); $parm = $request->get_parms( @@ -25,46 +24,80 @@ $parm = $request->get_parms( , 'debug' ); -phrasea::headers(200, true, 'application/json', 'UTF-8', false); -if ($parm['debug']) - print("
");
+phrasea::headers(200, true, 'application/json', 'UTF-8', false);
 
 $dbname = null;
 
 $result = array('n_recsChanged' => 0); // , 'n_termsDeleted'=>0, 'n_termsReplaced'=>0);
 
-try {
+$appbox = \appbox::get_instance(\bootstrap::getCore());
 
-    $databox = databox::get_instance((int) $parm['sbid']);
+try {
+    $databox = $appbox->get_databox((int) $parm['sbid']);
+    $connbas = $databox->get_connection();
     $domth = $databox->get_dom_thesaurus();
     $domct = $databox->get_dom_cterms();
 
+    // delete the branch from the cterms
+
     if ($domth && $domct) {
+
+        $lid = '';
+        $tsyid = array();
+        $tvals = array();
         $xpathct = new DOMXPath($domct);
 
+        if ($parm['debug']) {
+            printf("cterms before :\n%s \n", $domct->saveXML());
+        }
+
+        $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);
+            $w = $sy->getAttribute('w');
 
             $candidate = array('a' => $sy->getAttribute('v'), 'u' => $sy->getAttribute('w'));
-            if (($k = $sy->getAttribute('k')))
+            if (($k = $sy->getAttribute('k'))) {
                 $candidate['u'] .= ' (' . $k . ')';
-            if ($parm['debug'])
+            }
+            if ($parm['debug']) {
                 printf("%s : candidate = %s \n", __LINE__, var_export($candidate, true));
+            }
 
             $syid = str_replace('.', 'd', $sy->getAttribute('id')) . 'd';
+            $lid .= ( $lid ? ',' : '') . "'" . $syid . "'";
             $field = $sy->parentNode->parentNode->getAttribute('field');
 
+            $tsyid[$syid] = array('w'     => $w, 'field' => $field);
+
+            if (!array_key_exists($field, $tvals)) {
+                $tvals[$field] = array();
+            }
+            $tvals[$field][] = $w;
+
             // remove candidate from cterms
             $te = $sy->parentNode;
             $te->parentNode->removeChild($te);
 
-            $databox->saveCterms($domct);
+            if ($lid == '') {
+                // no cterm was found
+                continue;
+            }
+
+
+            if ($parm['debug']) {
+                printf("cterms after :\n%s \n", $domct->saveXML());
+            }
+            if (!$parm['debug']) {
+                $databox->saveCterms($domct);
+            }
 
             $sql = 'SELECT t.record_id, r.xml
               FROM thit AS t INNER JOIN record AS r USING(record_id)
@@ -76,135 +109,106 @@ try {
             $rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
             $stmt->closeCursor();
 
-            if ($parm['debug'])
-                printf("%s : %s \n", __LINE__, $sql);
+            if ($parm['debug']) {
+                printf("%s : SQL=%s \n", __LINE__, $sql);
+            }
 
             $t_rid = array();
             foreach ($rs as $rowbas) {
                 $rid = $rowbas['record_id'];
-                if ( ! array_key_exists('' . $rid, $t_rid))
+                if (!array_key_exists('' . $rid, $t_rid)) {
                     $t_rid['' . $rid] = $rowbas['xml'];
+                }
             }
-            if ($parm['debug'])
+            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)
+            foreach ($parm['t'] as $t) {
                 $replacing[] = simplified($t);
-            if ($parm['debug'])
+            }
+            if ($parm['debug']) {
                 printf("%s : replacing=%s \n", __LINE__, var_export($replacing, true));
+            }
 
-
+            $unicode = new unicode;
             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("(%d) ======== working on record_id = %d ======= \n", __LINE__, $rid);
                 }
-                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'];
+                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 ($parm['debug']) {
+                            printf("(%d) field '%s'  meta_struct_id=%s \n", __LINE__, $field->get_name(), $meta_struct_id);
+                        }
+
+                        /* @var $v caption_Field_Value */
+                        foreach ($field->get_values() as $v) {
+                            $vtxt = $unicode->remove_indexer_chars($v->getValue());
+                            $keep = true;
+                            foreach ($tvals as $fname => $vals) {
+                                if ($field->get_name() == $fname) {
+                                    if (in_array($vtxt, $vals)) {
+                                        $keep = false;
+                                    }
+                                }
+                            }
+                            if ($parm['debug']) {
+                                printf("(%d) ...v = '%s'  %s \n", __LINE__, $vtxt, ($keep ? '' : '!!! drop !!!'));
+                            }
+                            if ($keep) {
+                                $metadatask[] = array(
+                                    'meta_struct_id' => $meta_struct_id,
+                                    'meta_id'        => $v->getId(),
+                                    'value'          => $v->getValue()
+                                );
+                            } else {
+                                $r = array_shift($replacing);
+                                $metadatasd[] = array(
+                                    'meta_struct_id' => $meta_struct_id,
+                                    'meta_id'        => $v->getId(),
+                                    'value'          => $r['a']
+                                );
+                                foreach ($replacing as $r) {
+                                    $metadatasd[] = array(
+                                        'meta_struct_id' => $meta_struct_id,
+                                        'meta_id'        => null,
+                                        'value'          => $r['a']
+                                    );
+                                }
+                            }
+                        }
                     }
-                    if ($parm['debug'])
-                        printf("%s : after replace to t_mval %s \n", __LINE__, var_export($t_mval, true));
+
+                    if ($parm['debug']) {
+                        //                       printf("metadatas-keep :\n");
+                        //                       var_dump($metadatask);
+                        printf("metadatas-delete :\n");
+                        var_dump($metadatasd);
+                    }
+
+                    if (!$parm['debug']) {
+                        foreach (array('idx', 'prop', 'thit') as $t) {
+                            $sql = 'DELETE FROM ' . $t . ' WHERE record_id = :record_id';
+                            $stmt = $connbas->prepare($sql);
+                            $stmt->execute(array(':record_id' => $rid));
+                            $stmt->closeCursor();
+                        }
+                        $record->set_metadatas($metadatasd, true);
+                    }
+                } catch (Exception $e) {
+
                 }
-
-                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'] ++;
             }
         }
     }
@@ -226,9 +230,6 @@ function simplified($t)
 }
 print(p4string::jsonencode(array('parm'   => $parm, 'result' => $result)));
 
-if ($parm['debug'])
-    print("
"); - function splitTermAndContext($word) { $term = trim($word); From 2a75b76f32b25275f68e0d562a43dab8cd0bcffe Mon Sep 17 00:00:00 2001 From: jygaulier Date: Tue, 30 Oct 2012 15:08:45 +0100 Subject: [PATCH 07/22] =?UTF-8?q?fix=20#977=20(redirection=20vers=20collec?= =?UTF-8?q?tion=20dans=20task=20archive)=20fix=20#969=20(arr=C3=AAt=20de?= =?UTF-8?q?=20la=20task=20d'archivage)=20fix=20#982=20(symfony/process=20r?= =?UTF-8?q?eturnValue=20=3D=20-1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/classes/task/Scheduler.class.php | 14 +++++++++++++- lib/classes/task/period/archive.class.php | 14 +++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/lib/classes/task/Scheduler.class.php b/lib/classes/task/Scheduler.class.php index 03d85ca820..49b58fda29 100755 --- a/lib/classes/task/Scheduler.class.php +++ b/lib/classes/task/Scheduler.class.php @@ -33,6 +33,7 @@ class task_Scheduler public function __construct(Logger $logger) { + declare(ticks = 1); $this->logger = $logger; } @@ -52,6 +53,14 @@ class task_Scheduler * @throws Exception if scheduler is already running * @todo doc all possible exception */ + public function sigHandler($signal) + { + $status = null; + $pid = pcntl_wait($status); + $exitstatus = pcntl_wexitstatus ( $status ); + $this->log(sprintf("sigchild %s received from pid=%s, status=%s, exitstatus=%s\n", $signal, $pid, var_export($status, true), $exitstatus)); + } + public function run() { @@ -73,7 +82,10 @@ class task_Scheduler if (\task_manager::isPosixPcntlSupported()) { // avoid php when a task ends - pcntl_signal(SIGCHLD, SIG_IGN); + // pcntl_signal(SIGCHLD, SIG_IGN); // no zombies but no returnValue + // pcntl_signal(SIGCHLD, SIG_DFL); // with "declare(ticks=1)" returnValue ok but zombies + pcntl_signal(SIGCHLD, array($this, 'sigHandler')); // ok + $this->method = self::METHOD_FORK; } diff --git a/lib/classes/task/period/archive.class.php b/lib/classes/task/period/archive.class.php index 398a209903..b41914a6e0 100755 --- a/lib/classes/task/period/archive.class.php +++ b/lib/classes/task/period/archive.class.php @@ -145,7 +145,7 @@ class task_period_archive extends task_abstract public function xml2graphic($xml, $form) { // XML should always be valid here... - if (($sxml = simplexml_load_string($xml)) != false) { + if ( ($sxml = simplexml_load_string($xml)) ) { // sanitize values if ((int) ($sxml->period) < 10) { $sxml->period = 10; @@ -298,7 +298,7 @@ class task_period_archive extends task_abstract $this->period = 60; $this->cold = 30; - if (($this->sxBasePrefs = simplexml_load_string($collection->get_prefs())) != false) { + if ( ($this->sxBasePrefs = simplexml_load_string($collection->get_prefs())) ) { $this->sxBasePrefs["id"] = $base_id; $this->period = (int) ($this->sxTaskSettings->period); @@ -397,7 +397,7 @@ class task_period_archive extends task_abstract $this->setLastExecTime(); try { - if ( ! ($this->sxTaskSettings = @simplexml_load_string($this->getSettings()))) { + if ( !($this->sxTaskSettings = @simplexml_load_string($this->getSettings())) ) { throw new Exception(sprintf('Error fetching or reading settings of the task \'%d\'', $this->getID())); } else { // copy settings to task, so it's easier to get later @@ -609,10 +609,10 @@ class task_period_archive extends task_abstract if ($this->movedFiles) { // something happened : a least one file has moved - return self::STATE_MAXRECSDONE; + return 'MAXRECSDONE'; } elseif (memory_get_usage() >> 20 > 25) { - return self::STATE_MAXMEGSREACHED; + return 'MAXMEGSREACHED'; } else { return 'NORECSTODO'; @@ -693,7 +693,7 @@ class task_period_archive extends task_abstract try { $listFolder = new CListFolder($path); - if (($sxDotPhrasea = @simplexml_load_file($path . '/.phrasea.xml')) != false) { + if ( ($sxDotPhrasea = @simplexml_load_file($path . '/.phrasea.xml')) ) { // test for magic file if (($magicfile = trim((string) ($sxDotPhrasea->magicfile))) != '') { @@ -800,7 +800,7 @@ class task_period_archive extends task_abstract $xp = new DOMXPath($dom); - if (($sxDotPhrasea = @simplexml_load_file($path . '/.phrasea.xml')) != false) { + if ( ($sxDotPhrasea = @simplexml_load_file($path . '/.phrasea.xml')) ) { // test magicfile if (($magicfile = trim((string) ($sxDotPhrasea->magicfile))) != '') { From e9b17372919e55fb0340af164d00d3c4619da6ea Mon Sep 17 00:00:00 2001 From: jygaulier Date: Wed, 31 Oct 2012 20:18:33 +0100 Subject: [PATCH 08/22] CS --- lib/classes/task/Scheduler.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/classes/task/Scheduler.class.php b/lib/classes/task/Scheduler.class.php index 49b58fda29..5606d4c20b 100755 --- a/lib/classes/task/Scheduler.class.php +++ b/lib/classes/task/Scheduler.class.php @@ -57,7 +57,7 @@ class task_Scheduler { $status = null; $pid = pcntl_wait($status); - $exitstatus = pcntl_wexitstatus ( $status ); + $exitstatus = pcntl_wexitstatus($status); $this->log(sprintf("sigchild %s received from pid=%s, status=%s, exitstatus=%s\n", $signal, $pid, var_export($status, true), $exitstatus)); } From 0a84e02106203d44485f5391bb4c410740e2d633 Mon Sep 17 00:00:00 2001 From: jygaulier Date: Tue, 6 Nov 2012 13:56:16 +0100 Subject: [PATCH 09/22] dialog content set server side --- www/xmlhttp/replacecandidate.j.php | 347 +++++++++++++++-------------- 1 file changed, 176 insertions(+), 171 deletions(-) diff --git a/www/xmlhttp/replacecandidate.j.php b/www/xmlhttp/replacecandidate.j.php index c851c904f5..aa6537fc23 100644 --- a/www/xmlhttp/replacecandidate.j.php +++ b/www/xmlhttp/replacecandidate.j.php @@ -18,153 +18,171 @@ require_once __DIR__ . "/../../lib/bootstrap.php"; $request = http_request::getInstance(); $parm = $request->get_parms( - 'sbid' - , 'cid' // candidate (id) to replace - , 't' // replacing term - , 'debug' + 'id', + 't', + 'debug' ); -phrasea::headers(200, true, 'application/json', 'UTF-8', false); +define('SEARCH_REPLACE_MAXREC', 25); -$dbname = null; +$tsbas = array(); -$result = array('n_recsChanged' => 0); // , 'n_termsDeleted'=>0, 'n_termsReplaced'=>0); +$ret = array( + 'ctermsDeleted'=>array(), + 'maxRecsUpdatable'=>SEARCH_REPLACE_MAXREC, + 'nRecsToUpdate'=>0, + 'nRecsUpdated'=>0, + 'msg'=>'' +); + +foreach ($parm['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 ($parm['debug']) { + var_dump($tsbas); +} $appbox = \appbox::get_instance(\bootstrap::getCore()); -try { - $databox = $appbox->get_databox((int) $parm['sbid']); - $connbas = $databox->get_connection(); - $domth = $databox->get_dom_thesaurus(); - $domct = $databox->get_dom_cterms(); - // delete the branch from the cterms +// first, count the number of records to update +foreach ($tsbas as $ksbas=>$sbas) { - if ($domth && $domct) { + /* @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; + } - $lid = ''; - $tsyid = array(); - $tvals = array(); - $xpathct = new DOMXPath($domct); + if ( ! $tsbas[$ksbas]['domct']) { + continue; + } - if ($parm['debug']) { - printf("cterms before :\n%s \n", $domct->saveXML()); - } - - $xpathct = new DOMXPath($domct); - $field = null; - $x = null; - - $xp = '//te[@id="' . $parm['cid'] . '"]/sy'; + $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); - $w = $sy->getAttribute('w'); - - $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'; $lid .= ( $lid ? ',' : '') . "'" . $syid . "'"; $field = $sy->parentNode->parentNode->getAttribute('field'); - $tsyid[$syid] = array('w' => $w, 'field' => $field); - - if (!array_key_exists($field, $tvals)) { - $tvals[$field] = array(); + if ( ! array_key_exists($field, $tsbas[$ksbas]['tvals'])) { + $tsbas[$ksbas]['tvals'][$field] = array(); } - $tvals[$field][] = $w; + $tsbas[$ksbas]['tvals'][$field][] = $sy; + } + } - // remove candidate from cterms - $te = $sy->parentNode; - $te->parentNode->removeChild($te); + if ($lid == '') { + // no cterm was found + continue; + } + $tsbas[$ksbas]['lid'] = $lid; - if ($lid == '') { - // no cterm was found - continue; - } + // 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 ($parm['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 ($parm['debug']) { + printf("(%d) nRecsToUpdate = %d \ntsbas: \n", __LINE__, $ret['nRecsToUpdate']); + print_r($tsbas); +} + + +if($ret['nRecsToUpdate'] < SEARCH_REPLACE_MAXREC) +{ + $unicode = new unicode; + 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 ($parm['debug']) { - printf("cterms after :\n%s \n", $domct->saveXML()); - } - if (!$parm['debug']) { - $databox->saveCterms($domct); + printf("(%d) ======== working on record_id = %d ======= \n", __LINE__, $rid); } + try { + $record = $databox->get_record($rid); - $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'; + $metadatask = array(); // datas to keep + $metadatasd = array(); // datas to delete - $stmt = $connbas->prepare($sql); - $stmt->execute(array(':syn_id' => $syid)); - $rs = $stmt->fetchAll(PDO::FETCH_ASSOC); - $stmt->closeCursor(); + /* @var $field caption_field */ + foreach ($record->get_caption()->get_fields(null, true) as $field) { + $meta_struct_id = $field->get_meta_struct_id(); + if ($parm['debug']) { + printf("(%d) field '%s' meta_struct_id=%s \n", __LINE__, $field->get_name(), $meta_struct_id); + } - if ($parm['debug']) { - printf("%s : SQL=%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)); - } - - $unicode = new unicode; - foreach ($t_rid as $rid => $xml) { - if ($parm['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 ($parm['debug']) { - printf("(%d) field '%s' meta_struct_id=%s \n", __LINE__, $field->get_name(), $meta_struct_id); - } - - /* @var $v caption_Field_Value */ + /* @var $v caption_Field_Value */ + $fname = $field->get_name(); + if(!array_key_exists($fname, $sbas['tvals'])) { + foreach ($field->get_values() as $v) { + if ($parm['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) { - $vtxt = $unicode->remove_indexer_chars($v->getValue()); $keep = true; - foreach ($tvals as $fname => $vals) { - if ($field->get_name() == $fname) { - if (in_array($vtxt, $vals)) { - $keep = false; - } + $vtxt = $unicode->remove_indexer_chars($v->getValue()); + foreach($sbas['tvals'][$fname] as $sy) { + if ($sy->getAttribute('w') == $vtxt) { + $keep = false; } } + if ($parm['debug']) { - printf("(%d) ...v = '%s' %s \n", __LINE__, $vtxt, ($keep ? '' : '!!! drop !!!')); + printf("(%d) ...v = '%s' (meta_id=%s) %s \n", __LINE__, $v->getValue(), $v->getId(), ($keep ? '' : '!!! drop !!!')); } if ($keep) { $metadatask[] = array( @@ -173,76 +191,63 @@ try { 'value' => $v->getValue() ); } else { - $r = array_shift($replacing); $metadatasd[] = array( 'meta_struct_id' => $meta_struct_id, 'meta_id' => $v->getId(), - 'value' => $r['a'] + 'value' => $parm['t'] ? $parm['t'] : '' ); - foreach ($replacing as $r) { - $metadatasd[] = array( - 'meta_struct_id' => $meta_struct_id, - 'meta_id' => null, - 'value' => $r['a'] - ); - } } } } - - if ($parm['debug']) { - // printf("metadatas-keep :\n"); - // var_dump($metadatask); - printf("metadatas-delete :\n"); - var_dump($metadatasd); - } - - if (!$parm['debug']) { - foreach (array('idx', 'prop', 'thit') as $t) { - $sql = 'DELETE FROM ' . $t . ' WHERE record_id = :record_id'; - $stmt = $connbas->prepare($sql); - $stmt->execute(array(':record_id' => $rid)); - $stmt->closeCursor(); - } - $record->set_metadatas($metadatasd, true); - } - } catch (Exception $e) { - } + + if ($parm['debug']) { + printf("(%d) metadatask: \n", __LINE__); + var_dump($metadatask); + printf("(%d) metadatasd: \n", __LINE__); + var_dump($metadatasd); + } + + if(count($metadatasd) > 0) { + if ( ! $parm['debug']) { + $record->set_metadatas($metadatasd, true); + $ret['nRecsUpdated']++; + } + } + } catch (\Exception $e) { + continue; } } - } -} 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))); - -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)); + // delete the branch from the cterms + if ($parm['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 ($parm['debug']) { + printf("cterms after :\n%s \n", $sbas['domct']->saveXML()); + } + if ( ! $parm['debug']) { + $databox->saveCterms($sbas['domct']); } - } - return(array($term, $context)); + } + $ret['msg'] = sprintf(_('%s records updated'), $ret['nRecsUpdated']); } +else { + // too many records to update + $ret['msg'] = _('too many records to update'); +} + + +/** + * @todo respecter les droits d'editing par collections + */ +print(p4string::jsonencode($ret)); From 8beeaebdab1dbfe455bf304334b31770ea87715c Mon Sep 17 00:00:00 2001 From: jygaulier Date: Wed, 31 Oct 2012 20:38:19 +0100 Subject: [PATCH 10/22] restore prod / thesaurus : delete or replace candidates --- templates/web/prod/thesaurus.js | 112 +++++++------ www/xmlhttp/deletecandidates.j.php | 253 ----------------------------- 2 files changed, 63 insertions(+), 302 deletions(-) delete mode 100644 www/xmlhttp/deletecandidates.j.php diff --git a/templates/web/prod/thesaurus.js b/templates/web/prod/thesaurus.js index 01aba83703..20fa9cee2e 100644 --- a/templates/web/prod/thesaurus.js +++ b/templates/web/prod/thesaurus.js @@ -1,4 +1,3 @@ - function thesau_show() { if(p4.thesau.currentWizard == "???") // first show of thesaurus @@ -213,27 +212,16 @@ function T_filter_delayed2(f, delay, mode) // ====================================================================================================== - - function T_replaceCandidates_OK(dlgnode) { - $("#THPD_confirm_replace_dlg_msg").html("{% trans 'prod::thesaurusTab:dlg:Remplacement en cours.' %}"); - - // 3 cases - // the new term already exists (possibly many times) in the thesaurus - // the new term already exists in the candidates - // the new term is brand new - - // the simpliest solution is to replace the terms and let the indexer work - + $(dlgnode).dialog().html("{% trans 'prod::thesaurusTab:dlg:Remplacement en cours.' %}"); var parms = { url: "/xmlhttp/replacecandidate.j.php", data: { - "sbid" : trees.C._toReplace.sbas - , "cid" : trees.C._toReplace.cid - , "t" : trees.C._toReplace.replaceby - // , "debug" : '1' + "id[]" : trees.C._toReplace.sbas + "." + trees.C._toReplace.cid + , "t" : trees.C._toReplace.replaceby + , "debug" : '0' }, async: false, cache: false, @@ -243,7 +231,21 @@ function T_replaceCandidates_OK(dlgnode) { trees.C._toReplace = null; thesauShowWizard("wiz_0", false); + $(dlgnode).dialog("close"); + var msg = $.sprintf("{% trans 'prod::thesaurusTab:dlg: %s record(s) updated' %}", result.nRecsUpdated); + if(result.msg != '') + { + msg = result.msg + '\n' + msg; + } + alert(msg); + + for(i in result.ctermsDeleted) + { + var cid = "#CX_P\\." + result.ctermsDeleted[i].replace(new RegExp("\\.", "g"), "\\."); // escape les '.' pour jquery + $(cid).remove(); + } + }, _ret: null // private alchemy }; @@ -254,7 +256,7 @@ function T_replaceCandidates_OK(dlgnode) function T_acceptCandidates_OK(dlgnode) { - $("#THPD_confirm_accept_dlg_msg").html("{% trans 'prod::thesaurusTab:dlg:Acceptation en cours.' %}"); + $(dlgnode).dialog().html("{% trans 'prod::thesaurusTab:dlg:Acceptation en cours.' %}"); var t_ids = []; var dst = trees.C._toAccept.dst.split('.'); @@ -264,20 +266,19 @@ function T_acceptCandidates_OK(dlgnode) same_sbas = true; // obviously the candidates and the target already complies (same sbas, good tbranch) trees.C._selInfos.sel.each( - function() - { - var x = this.getAttribute('id').split('.'); - x.shift(); - if(x.shift() != sbid) - same_sbas = false; - t_ids.push(x.join('.')); - } -); + function() + { + var x = this.getAttribute('id').split('.'); + x.shift(); + if(x.shift() != sbid) + same_sbas = false; + t_ids.push(x.join('.')); + } + ); if(!same_sbas) return; - var parms = { url: "/xmlhttp/acceptcandidates.j.php", data: { @@ -319,8 +320,6 @@ function T_acceptCandidates_OK(dlgnode) } , "json"); } - - // $("#THPD_confirm_accept_dlg_msg").dialog("close"); }, error:function(){}, timeout:function(){}, @@ -331,22 +330,22 @@ function T_acceptCandidates_OK(dlgnode) } -function C_deleteCandidates_OK() +function C_deleteCandidates_OK(dlgnode) { - $("#THPD_confirm_del_dlg_msg").html("{% trans 'prod::thesaurusTab:dlg:Suppression en cours.' %}"); + $(dlgnode).dialog().html("{% trans 'prod::thesaurusTab:dlg:Suppression en cours.' %}"); var t_ids = []; var lisel = trees.C.tree.find("LI .selected"); trees.C.tree.find("LI .selected").each( - function() - { - var x = this.getAttribute('id').split('.'); - x.shift(); - t_ids.push(x.join('.')); - } -); + function() + { + var x = this.getAttribute('id').split('.'); + x.shift(); + t_ids.push(x.join('.')); + } + ); var parms = { - url:"/xmlhttp/deletecandidates.j.php", + url:"/xmlhttp/replacecandidate.j.php", data:{"id[]":t_ids}, async:false, cache:false, @@ -354,12 +353,20 @@ function C_deleteCandidates_OK() timeout:10*60*1000, // 10 minutes ! success: function(result, textStatus) { - for(i in result) + $(dlgnode).dialog("close"); + + var msg = $.sprintf("{% trans 'prod::thesaurusTab:dlg: %s record(s) updated' %}", result.nRecsUpdated); + if(result.msg != '') { - var cid = "#CX_P\\." + result[i].replace(new RegExp("\\.", "g"), "\\."); // escape les '.' pour jquery + msg = result.msg + '\n' + msg; + } + alert(msg); + + for(i in result.ctermsDeleted) + { + var cid = "#CX_P\\." + result.ctermsDeleted[i].replace(new RegExp("\\.", "g"), "\\."); // escape les '.' pour jquery $(cid).remove(); } - $("#THPD_confirm_del_dlg").dialog("close"); }, _ret: null }; @@ -1138,15 +1145,14 @@ function startThesaurus(){ buttons:{ "{% trans 'boutton::ok' %}":function() { - C_deleteCandidates_OK(); + C_deleteCandidates_OK(this); }, "{% trans 'boutton::annuler' %}":function() { $(this).dialog("close"); } } - } -); + }); $("#THPD_confirm_accept_dlg").dialog( { @@ -1165,8 +1171,7 @@ function startThesaurus(){ $(this).dialog("close"); } } - } -); + }); $("#THPD_confirm_replace_dlg").dialog( { @@ -1185,8 +1190,7 @@ function startThesaurus(){ $(this).dialog("close"); } } - } -); + }); trees.T.tree.contextMenu( @@ -1341,6 +1345,16 @@ function startThesaurus(){ // glue selection info to the tree trees.C._selInfos = {'sel':lisel, 'field':field, 'sbas':sbas, 'n':lisel.length} ; + +// $(this.menu).find('.context-menu-item')[{{ thesau_languages|length }}].addClass('context-menu-item-disabled'); + if(lisel.length == 1) + { + $(this.menu).find('.context-menu-item').eq({{ thesau_languages|length }}).removeClass('context-menu-item-disabled'); + } + else + { + $(this.menu).find('.context-menu-item').eq({{ thesau_languages|length }}).addClass('context-menu-item-disabled'); + } } else { diff --git a/www/xmlhttp/deletecandidates.j.php b/www/xmlhttp/deletecandidates.j.php deleted file mode 100644 index 86ad000fea..0000000000 --- a/www/xmlhttp/deletecandidates.j.php +++ /dev/null @@ -1,253 +0,0 @@ -get_parms( - 'id', 'debug' -); - -phrasea::headers(200, true, 'application/json', 'UTF-8', false); - -define('SEARCH_REPLACE_MAXREC', 25); - -$tsbas = array(); - -$ret = array( - 'maxRecsUpdatable'=>SEARCH_REPLACE_MAXREC, - 'nRecsToUpdate'=>0, - 'nRecsUpdated'=>0, - 'msg'=>'' -); - -foreach ($parm['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 ($parm['debug']) { - var_dump($tsbas); -} - -$appbox = \appbox::get_instance(\bootstrap::getCore()); - - -// 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 ($parm['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 ($parm['debug']) { - printf("(%d) nRecsToUpdate = %d \ntsbas: \n", __LINE__, $ret['nRecsToUpdate']); - print_r($tsbas); -} - - -if($ret['nRecsToUpdate'] < SEARCH_REPLACE_MAXREC) -{ - $unicode = new unicode; - foreach ($tsbas as $sbas) { - - /* @var $databox databox */ - try { - $databox = $appbox->get_databox($sbas['sbas_id']); - $connbas = $databox->get_connection(); - } catch (Exception $e) { - continue; - } - - // delete the branch from the cterms - if ($parm['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); - } - } - if ($parm['debug']) { - printf("cterms after :\n%s \n", $sbas['domct']->saveXML()); - } - if ( ! $parm['debug']) { - $databox->saveCterms($sbas['domct']); - } - - // fix caption of records - foreach ($sbas['trids'] as $rid) { - - if ($parm['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 ($parm['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 ($parm['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 = $unicode->remove_indexer_chars($v->getValue()); - foreach($sbas['tvals'][$fname] as $sy) { - if ($sy->getAttribute('w') == $vtxt) { - $keep = false; - } - } - - if ($parm['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' => '' - ); - } - } - } - } - - if ($parm['debug']) { - printf("(%d) metadatas: \n", __LINE__); - var_dump($metadatasd); - } - - if(count($metadatasd) > 0) { - if ( ! $parm['debug']) { -// foreach (array('idx', 'prop', 'thit') as $t) { -// $sql = 'DELETE FROM ' . $t . ' WHERE record_id = :record_id'; -// $stmt = $connbas->prepare($sql); -// $stmt->execute(array(':record_id' => $rid)); -// $stmt->closeCursor(); -// } - $record->set_metadatas($metadatasd, true); - $ret['nRecsUpdated']++; - } - } - } catch (\Exception $e) { - continue; - } - } - } -} -else { - // too many records to update - $ret['msg'] = 'too many records to update'; -} - - - -/** - * @todo respecter les droits d'editing par collections - */ -print(p4string::jsonencode($ret)); From 980055cb313997fc354d8ab8bbb867c5a24cd348 Mon Sep 17 00:00:00 2001 From: jygaulier Date: Mon, 5 Nov 2012 14:19:14 +0100 Subject: [PATCH 11/22] small fix --- www/xmlhttp/replacecandidate.j.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/xmlhttp/replacecandidate.j.php b/www/xmlhttp/replacecandidate.j.php index aa6537fc23..ca2e09e7f7 100644 --- a/www/xmlhttp/replacecandidate.j.php +++ b/www/xmlhttp/replacecandidate.j.php @@ -125,7 +125,7 @@ if ($parm['debug']) { } -if($ret['nRecsToUpdate'] < SEARCH_REPLACE_MAXREC) +if($ret['nRecsToUpdate'] <= SEARCH_REPLACE_MAXREC) { $unicode = new unicode; foreach ($tsbas as $sbas) { From f19d9dd1e814b4c127f1a3712489c64f219a8ba9 Mon Sep 17 00:00:00 2001 From: jygaulier Date: Mon, 5 Nov 2012 14:59:23 +0100 Subject: [PATCH 12/22] fix #992 --- templates/web/prod/thesaurus.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/templates/web/prod/thesaurus.js b/templates/web/prod/thesaurus.js index 20fa9cee2e..e0bf654a29 100644 --- a/templates/web/prod/thesaurus.js +++ b/templates/web/prod/thesaurus.js @@ -669,14 +669,16 @@ function CXdblClick(e) { case "SPAN": // term var li = $(x).closest('li'); - var tid = li.attr('id'); - if(tid.substr(0,5)=="CX_P.") + var field = li.closest('[field]').attr('field'); + if(typeof(field) != "undefined") { - var sbid = tid.split(".")[1]; - var term = $(x).text(); - var field = li.closest('[field]').attr('field'); - - doThesSearch('C', sbid, term, field); + var tid = li.attr('id'); + if(tid.substr(0,5)=="CX_P.") + { + var sbid = tid.split(".")[1]; + var term = $(x).text(); + doThesSearch('C', sbid, term, field); + } } break; default: From 5f6936ae9adcbc0e27a9805b73090f741c6d8d3f Mon Sep 17 00:00:00 2001 From: jygaulier Date: Mon, 5 Nov 2012 19:47:07 +0100 Subject: [PATCH 13/22] change js alert to dialogs --- templates/web/prod/thesaurus.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/templates/web/prod/thesaurus.js b/templates/web/prod/thesaurus.js index e0bf654a29..d7c4336d31 100644 --- a/templates/web/prod/thesaurus.js +++ b/templates/web/prod/thesaurus.js @@ -238,7 +238,13 @@ function T_replaceCandidates_OK(dlgnode) { msg = result.msg + '\n' + msg; } - alert(msg); + + var alert = p4.Dialog.Create({ + size : 'Alert', + closeOnEscape : true, + closeButton:true + }); + alert.setContent(msg); for(i in result.ctermsDeleted) { @@ -360,7 +366,13 @@ function C_deleteCandidates_OK(dlgnode) { msg = result.msg + '\n' + msg; } - alert(msg); + + var alert = p4.Dialog.Create({ + size : 'Alert', + closeOnEscape : true, + closeButton:true + }); + alert.setContent(msg); for(i in result.ctermsDeleted) { @@ -837,7 +849,7 @@ function replaceEditSel(value) { if(!p4.thesau.lastTextfocus || !p4.thesau.lastTextfocus.selectedTerm) return; - // alert(textarea.selectedTerm.start + " ; " + textarea.selectedTerm.end); + p4.thesau.lastTextfocus.value = p4.thesau.lastTextfocus.value.substr(0, p4.thesau.lastTextfocus.selectedTerm.start) + value + p4.thesau.lastTextfocus.value.substr(p4.thesau.lastTextfocus.selectedTerm.end); if(typeof(document.selection) != 'undefined') { From f36d37c41b784a7bad1833ac5e4f9b17088602ff Mon Sep 17 00:00:00 2001 From: jygaulier Date: Tue, 6 Nov 2012 10:24:08 +0100 Subject: [PATCH 14/22] dialog content set server side --- templates/web/prod/thesaurus.js | 35 +++++++++++------------------- www/xmlhttp/replacecandidate.j.php | 2 +- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/templates/web/prod/thesaurus.js b/templates/web/prod/thesaurus.js index d7c4336d31..bf609e409d 100644 --- a/templates/web/prod/thesaurus.js +++ b/templates/web/prod/thesaurus.js @@ -233,19 +233,17 @@ function T_replaceCandidates_OK(dlgnode) thesauShowWizard("wiz_0", false); $(dlgnode).dialog("close"); - var msg = $.sprintf("{% trans 'prod::thesaurusTab:dlg: %s record(s) updated' %}", result.nRecsUpdated); + if(result.msg != '') { - msg = result.msg + '\n' + msg; + var alert = p4.Dialog.Create({ + size : 'Alert', + closeOnEscape : true, + closeButton:true + }); + alert.setContent(result.msg); } - var alert = p4.Dialog.Create({ - size : 'Alert', - closeOnEscape : true, - closeButton:true - }); - alert.setContent(msg); - for(i in result.ctermsDeleted) { var cid = "#CX_P\\." + result.ctermsDeleted[i].replace(new RegExp("\\.", "g"), "\\."); // escape les '.' pour jquery @@ -361,19 +359,16 @@ function C_deleteCandidates_OK(dlgnode) { $(dlgnode).dialog("close"); - var msg = $.sprintf("{% trans 'prod::thesaurusTab:dlg: %s record(s) updated' %}", result.nRecsUpdated); if(result.msg != '') { - msg = result.msg + '\n' + msg; + var alert = p4.Dialog.Create({ + size : 'Alert', + closeOnEscape : true, + closeButton:true + }); + alert.setContent(result.msg); } - var alert = p4.Dialog.Create({ - size : 'Alert', - closeOnEscape : true, - closeButton:true - }); - alert.setContent(msg); - for(i in result.ctermsDeleted) { var cid = "#CX_P\\." + result.ctermsDeleted[i].replace(new RegExp("\\.", "g"), "\\."); // escape les '.' pour jquery @@ -1134,10 +1129,6 @@ function startThesaurus(){ p4.thesau.lastClickedCandidate = null; - // $("#THPD_confirm_del_dlg").remove(); - // $("#THPD_confirm_accept_dlg").remove(); - // $("#THPD_confirm_replace_dlg").remove(); - p4.thesau.tabs = $("#THPD_tabs"); p4.thesau.tabs.tabs(); diff --git a/www/xmlhttp/replacecandidate.j.php b/www/xmlhttp/replacecandidate.j.php index ca2e09e7f7..765853e36f 100644 --- a/www/xmlhttp/replacecandidate.j.php +++ b/www/xmlhttp/replacecandidate.j.php @@ -243,7 +243,7 @@ if($ret['nRecsToUpdate'] <= SEARCH_REPLACE_MAXREC) } else { // too many records to update - $ret['msg'] = _('too many records to update'); + $ret['msg'] = sprintf(_('too many (%d) records to update (limit=%d)'), $ret['nRecsToUpdate'], SEARCH_REPLACE_MAXREC); } From b02c8d7ebbfd99762b49e123b32587bc96b6b086 Mon Sep 17 00:00:00 2001 From: Nicolas Le Goff Date: Tue, 6 Nov 2012 15:00:26 +0100 Subject: [PATCH 15/22] Fix #956 Bridge Apis account are now deletable --- lib/Alchemy/Phrasea/Application/Setup.php | 2 +- .../Phrasea/Controller/Prod/Bridge.php | 20 ++++++++++ .../web/prod/actions/Bridge/disconnected.twig | 3 ++ templates/web/prod/actions/Bridge/index.twig | 39 +++++++++++++++++++ .../Phrasea/Controller/Prod/BridgeTest.php | 23 ++++++++++- 5 files changed, 84 insertions(+), 3 deletions(-) diff --git a/lib/Alchemy/Phrasea/Application/Setup.php b/lib/Alchemy/Phrasea/Application/Setup.php index 18e06fb130..7cbc8b97dd 100644 --- a/lib/Alchemy/Phrasea/Application/Setup.php +++ b/lib/Alchemy/Phrasea/Application/Setup.php @@ -40,7 +40,7 @@ return call_user_func(function() { } elseif (\setup::needUpgradeConfigurationFile()) { if (\setup::requireGVUpgrade()) { - setup::upgradeGV($app['phraseanet.core']['Registry']); + \setup::upgradeGV($app['Core']['Registry']); } $connexionInc = new \SplFileInfo(__DIR__ . '/../../../../config/connexion.inc'); diff --git a/lib/Alchemy/Phrasea/Controller/Prod/Bridge.php b/lib/Alchemy/Phrasea/Controller/Prod/Bridge.php index d611678d25..ea5b97761d 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/Bridge.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/Bridge.php @@ -116,6 +116,26 @@ class Bridge implements ControllerProviderInterface return $app->redirect('/prod/bridge/adapter/' . $account_id . '/load-elements/' . $account->get_api()->get_connector()->get_default_element_type() . '/'); })->assert('account_id', '\d+'); + $controllers->post('/adapter/{account_id}/delete/' + , function($account_id) use ($app, $twig) { + $success = false; + $message = ''; + $appbox = \appbox::get_instance($app['Core']); + try { + $account = \Bridge_Account::load_account($appbox, $account_id); + + $account->delete(); + + $success = true; + } catch(\Bridge_Exception_AccountNotFound $e) { + $message = _('Current account could not be found.'); + } catch(\Exception $e) { + $message = _('Something went wront while deleting this account, please contact an administrator.'); + } + + return $app->json(array('success' => $success, 'message' => $message)); + })->assert('account_id', '\d+'); + $controllers->get('/adapter/{account_id}/load-records/' , function($account_id) use ($app, $twig) { $page = max((int) $app['request']->get('page'), 0); diff --git a/templates/web/prod/actions/Bridge/disconnected.twig b/templates/web/prod/actions/Bridge/disconnected.twig index 937e3784be..d3200275da 100644 --- a/templates/web/prod/actions/Bridge/disconnected.twig +++ b/templates/web/prod/actions/Bridge/disconnected.twig @@ -22,6 +22,9 @@
+ +
diff --git a/templates/web/prod/actions/Bridge/index.twig b/templates/web/prod/actions/Bridge/index.twig index 658fd62464..9da5c8a894 100644 --- a/templates/web/prod/actions/Bridge/index.twig +++ b/templates/web/prod/actions/Bridge/index.twig @@ -143,6 +143,45 @@ $(function() { return false; }); + $(".delete-account" , $panel).bind("click", function(){ + account_id = $(this).val(); + var buttons = {}; + + buttons[language.valider] = function() { + $.ajax({ + type: "POST", + dataType: "json", + url: "/prod/bridge/adapter/" + account_id + "/delete/", + data: {}, + success: function(datas){ + if(datas.success) { + confirmBox.Close(); + publicator_reload_publicator(); + } else { + confirmBox.Close(); + var alertBox = p4.Dialog.Create({ + size : 'Alert', + closeOnEscape : true, + closeButton:true + }, 2); + + alertBox.setContent(datas.message); + } + } + }); + }; + + var confirmBox = p4.Dialog.Create({ + size : 'Alert', + closeOnEscape : true, + closeButton:true, + cancelButton: true, + buttons: buttons + }, 2); + + confirmBox.setContent("{% trans 'You are about to delete this account. Would you like to continue ?' %}"); + }); + $('.form_submitter', $panel).bind('click', function(){ var $form = $(this).closest('form'); var method = $form.attr('method'); diff --git a/tests/Alchemy/Phrasea/Controller/Prod/BridgeTest.php b/tests/Alchemy/Phrasea/Controller/Prod/BridgeTest.php index 142863ca7f..fb63cd9a75 100644 --- a/tests/Alchemy/Phrasea/Controller/Prod/BridgeTest.php +++ b/tests/Alchemy/Phrasea/Controller/Prod/BridgeTest.php @@ -43,10 +43,10 @@ class BridgeApplication extends PhraseanetWebTestCaseAuthenticatedAbstract public function createApplication() { $app = require realpath(__DIR__ . '/../../../../../lib/Alchemy/Phrasea/Application/Prod.php'); - + $app['debug'] = true; unset($app['exception_handler']); - + return $app; } @@ -406,4 +406,23 @@ class BridgeApplication extends PhraseanetWebTestCaseAuthenticatedAbstract $response = $this->client->getResponse(); $this->assertTrue($response->isRedirect()); } + + public function testDeleteAccount() + { + $account = Bridge_Account::create(appbox::get_instance(\bootstrap::getCore()), self::$api, self::$user, 'hello', 'you'); + $url = "/bridge/" . $account->get_id() . "/delete/"; + $this->client->request('POST', $url); + $response = $this->client->getResponse(); + $this->assertTrue($response->isOk()); + $datas = json_decode($response->getContent(), true); + $this->assertArrayHasKey('success', $datas); + $this->assertTrue($datas['success']); + try { + \Bridge_Account::load_account(appbox::get_instance(\bootstrap::getCore()), $account->get_id()); + $this->fail('Account is not deleted'); + } catch(Bridge_Exception_AccountNotFound $e) { + + } + unset($account, $response); + } } From da6f7a00c028685e8b03a7d6cad4c85f67e46511 Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Mon, 5 Nov 2012 18:52:40 +0100 Subject: [PATCH 16/22] Fix simplexml calls --- lib/Alchemy/Phrasea/Helper/Prod.php | 2 +- lib/Alchemy/Phrasea/Helper/Record/Edit.php | 2 +- lib/Alchemy/Phrasea/Out/Module/PDF.php | 3 +- lib/classes/Bridge/Api/Youtube.class.php | 9 +++-- lib/classes/base.class.php | 5 ++- lib/classes/databox.class.php | 4 +-- lib/classes/databox/status.class.php | 2 +- lib/classes/deprecated/inscript.api.php | 2 +- lib/classes/geonames.class.php | 8 ++--- lib/classes/patch/370a8.class.php | 2 +- lib/classes/queries.class.php | 6 ++-- .../adapter/phrasea/engine.class.php | 2 +- lib/classes/setup.class.php | 4 +-- lib/classes/task/abstract.class.php | 8 ++--- lib/classes/task/period/RecordMover.class.php | 7 ++-- lib/classes/task/period/archive.class.php | 35 +++++++++---------- lib/classes/task/period/cindexer.class.php | 2 +- lib/classes/task/period/ftp.class.php | 3 +- lib/classes/task/period/ftpPull.class.php | 3 +- lib/classes/task/period/outofdate.class.php | 5 ++- lib/classes/task/period/subdef.class.php | 2 +- lib/classes/task/period/workflow01.class.php | 3 +- lib/classes/task/period/writemeta.class.php | 3 +- 23 files changed, 56 insertions(+), 66 deletions(-) diff --git a/lib/Alchemy/Phrasea/Helper/Prod.php b/lib/Alchemy/Phrasea/Helper/Prod.php index 8e2a309667..71fe041470 100644 --- a/lib/Alchemy/Phrasea/Helper/Prod.php +++ b/lib/Alchemy/Phrasea/Helper/Prod.php @@ -87,7 +87,7 @@ class Prod extends Helper if ( ! $user->ACL()->has_right_on_sbas($sbas_id, 'bas_modif_th')) continue; - if (simplexml_load_string($databox->get_cterms())) { + if (false !== simplexml_load_string($databox->get_cterms())) { $bases[$sbas_id]['cterms'] = true; } } diff --git a/lib/Alchemy/Phrasea/Helper/Record/Edit.php b/lib/Alchemy/Phrasea/Helper/Record/Edit.php index 2f20d6dcaf..48f613a1e4 100644 --- a/lib/Alchemy/Phrasea/Helper/Record/Edit.php +++ b/lib/Alchemy/Phrasea/Helper/Record/Edit.php @@ -314,7 +314,7 @@ class Edit extends RecordHelper $T_sgval['b' . $base_id] = array(); $collection = \collection::get_from_base_id($base_id); - if ($sxe = simplexml_load_string($collection->get_prefs())) { + if (false !== $sxe = simplexml_load_string($collection->get_prefs())) { $z = $sxe->xpath('/baseprefs/sugestedValues'); if ( ! $z || ! is_array($z)) diff --git a/lib/Alchemy/Phrasea/Out/Module/PDF.php b/lib/Alchemy/Phrasea/Out/Module/PDF.php index 4ec1b368b3..4df2720c90 100644 --- a/lib/Alchemy/Phrasea/Out/Module/PDF.php +++ b/lib/Alchemy/Phrasea/Out/Module/PDF.php @@ -354,8 +354,9 @@ class PDF $collection = \collection::get_from_base_id($rec->get_base_id()); $vn = ""; - if ($str = simplexml_load_string($collection->get_prefs())) + if (false !== $str = simplexml_load_string($collection->get_prefs())) { $vn = (string) ($str->pdfPrintappear); + } if ($vn == "" || $vn == "1") { $RIGHT_TEXT = \phrasea::bas_names($rec->get_base_id()); diff --git a/lib/classes/Bridge/Api/Youtube.class.php b/lib/classes/Bridge/Api/Youtube.class.php index 1de7016e78..45088d86a2 100644 --- a/lib/classes/Bridge/Api/Youtube.class.php +++ b/lib/classes/Bridge/Api/Youtube.class.php @@ -631,7 +631,7 @@ class Bridge_Api_Youtube extends Bridge_Api_Abstract implements Bridge_Api_Inter $xml = simplexml_load_string($string); libxml_clear_errors(); - if ( ! $xml) { + if (false === $xml) { return false; } @@ -723,11 +723,10 @@ class Bridge_Api_Youtube extends Bridge_Api_Abstract implements Bridge_Api_Inter $cat = array(); $url_cat = sprintf('%s?hl=%s', self::CATEGORY_URL, $this->get_locale()); - $cxml = @simplexml_load_file($url_cat); - - if ( ! $cxml) + if (false === $cxml = simplexml_load_file($url_cat)) { throw new Bridge_Exception_ApiConnectorRequestFailed('Failed to retrive youtube categories'); - + } + $cxml->registerXPathNamespace('atom', 'http://www.w3.org/2005/Atom'); $categories = $cxml->xpath('//atom:category'); diff --git a/lib/classes/base.class.php b/lib/classes/base.class.php index 0d369e4098..892859b80f 100644 --- a/lib/classes/base.class.php +++ b/lib/classes/base.class.php @@ -397,10 +397,9 @@ abstract class base implements cache_cacheableInterface return $this; } - $structure = simplexml_load_file(__DIR__ . "/../../lib/conf.d/bases_structure.xml"); - - if ( ! $structure) + if (false === $structure = simplexml_load_file(__DIR__ . "/../../lib/conf.d/bases_structure.xml")) { throw new Exception('Unable to load schema'); + } if ($this->get_base_type() === self::APPLICATION_BOX) $this->schema = $structure->appbox; diff --git a/lib/classes/databox.class.php b/lib/classes/databox.class.php index a033b0659b..1abb5a3335 100644 --- a/lib/classes/databox.class.php +++ b/lib/classes/databox.class.php @@ -1040,7 +1040,7 @@ class databox extends base $thesaurus = $this->get_thesaurus(); - if ($thesaurus && ($tmp = simplexml_load_string($thesaurus)) !== false) + if ($thesaurus && false !== $tmp = simplexml_load_string($thesaurus)) self::$_sxml_thesaurus[$sbas_id] = $tmp; else self::$_sxml_thesaurus[$sbas_id] = false; @@ -1205,7 +1205,7 @@ class databox extends base $structure = $this->get_structure(); - if ($structure && ($tmp = simplexml_load_string($structure)) !== false) + if ($structure && false !== $tmp = simplexml_load_string($structure)) $this->_sxml_structure = $tmp; else $this->_sxml_structure = false; diff --git a/lib/classes/databox/status.class.php b/lib/classes/databox/status.class.php index 73c47f79e5..5926efb949 100644 --- a/lib/classes/databox/status.class.php +++ b/lib/classes/databox/status.class.php @@ -75,7 +75,7 @@ class databox_status $xmlpref = $databox->get_structure(); $sxe = simplexml_load_string($xmlpref); - if ($sxe) { + if ($sxe !== false) { foreach ($sxe->statbits->bit as $sb) { $bit = (int) ($sb["n"]); diff --git a/lib/classes/deprecated/inscript.api.php b/lib/classes/deprecated/inscript.api.php index a8b66a38a8..1ecad3d4f6 100644 --- a/lib/classes/deprecated/inscript.api.php +++ b/lib/classes/deprecated/inscript.api.php @@ -111,7 +111,7 @@ function giveMeBases($usr = null) $collInscript = $baseInscript; $defined = false; $cguSpec = false; - if ($xml = simplexml_load_string($collection->get_prefs())) { + if (false !== $xml = simplexml_load_string($collection->get_prefs())) { $defined = true; foreach ($xml->xpath('/baseprefs/caninscript') as $caninscript) { $tmp = (string) $caninscript; diff --git a/lib/classes/geonames.class.php b/lib/classes/geonames.class.php index ef076bf794..92906374da 100644 --- a/lib/classes/geonames.class.php +++ b/lib/classes/geonames.class.php @@ -22,7 +22,7 @@ class geonames $sxe = simplexml_load_string($xml); - if ($sxe && ($geoname = $sxe->geoname)) { + if ($sxe !== false && ($geoname = $sxe->geoname)) { $ret = (string) $geoname->city . ', ' . (string) $geoname->country; } } @@ -46,7 +46,7 @@ class geonames if ($xml) { $sxe = simplexml_load_string($xml); - if ($sxe && ($geoname = $sxe->geoname)) { + if ($sxe !== false && ($geoname = $sxe->geoname)) { $ret = (string) $geoname->country; } } @@ -67,7 +67,7 @@ class geonames if ($xml) { $sxe = simplexml_load_string($xml); - if ($sxe && ($geoname = $sxe->geoname)) { + if ($sxe !== false && ($geoname = $sxe->geoname)) { $ret = (string) $geoname->country_code; } } @@ -150,7 +150,7 @@ class geonames $xml = http_query::getUrl($url); if ($xml) { $sxe = simplexml_load_string($xml); - if ($sxe && $sxe->geoname) { + if ($sxe !== false && $sxe->geoname) { $output['city'] = (string) $sxe->geoname->city; $output['country_code'] = (string) $sxe->geoname->country_code; $output['country'] = (string) $sxe->geoname->country; diff --git a/lib/classes/patch/370a8.class.php b/lib/classes/patch/370a8.class.php index b5b980090b..604bb80b9f 100644 --- a/lib/classes/patch/370a8.class.php +++ b/lib/classes/patch/370a8.class.php @@ -81,7 +81,7 @@ class patch_370a8 implements patchInterface * migrating task 'workflow01' or 'task_period_ftv' */ $x = $task['settings']; - if (($sx = simplexml_load_string($x)) !== FALSE) { + if (false !== $sx = simplexml_load_string($x)) { $period = (int) ($sx->period); if ( ! array_key_exists('_' . $period, $tdom)) { diff --git a/lib/classes/queries.class.php b/lib/classes/queries.class.php index 6a549a6c11..7a92364f1e 100644 --- a/lib/classes/queries.class.php +++ b/lib/classes/queries.class.php @@ -39,8 +39,8 @@ class queries } $cssTopics = ''; - if ($xmlTopics && ($sxTopics = simplexml_load_file($xmlTopics))) { - $cssTopics = (string) ($sxTopics->display->css); + if ($xmlTopics && false !== $sxTopics = simplexml_load_file($xmlTopics)) { + $cssTopics = (string) $sxTopics->display->css; } $out .= '