From 325071da63805d5bb9aca98aaa64e7d5b3790261 Mon Sep 17 00:00:00 2001 From: Sebastian Castro Date: Tue, 2 Jul 2024 18:39:29 +0000 Subject: [PATCH 01/42] Change List data structure + remove uneeded charset transformations --- .../20240502083251_RefactorListStruture.php | 26 ++++++ tools/bazar/controllers/ListController.php | 32 ++++---- tools/bazar/fields/EnumField.php | 20 ++--- tools/bazar/libs/bazar.edit_lists.js | 79 +++++++++++++------ tools/bazar/libs/bazar.fonct.php | 52 ++++++------ tools/bazar/services/ListManager.php | 68 ++++++++-------- tools/bazar/templates/lists/list_form.twig | 14 ++-- tools/bazar/templates/lists/list_table.twig | 33 ++++---- 8 files changed, 189 insertions(+), 135 deletions(-) create mode 100644 includes/migrations/20240502083251_RefactorListStruture.php diff --git a/includes/migrations/20240502083251_RefactorListStruture.php b/includes/migrations/20240502083251_RefactorListStruture.php new file mode 100644 index 000000000..55c5e4da0 --- /dev/null +++ b/includes/migrations/20240502083251_RefactorListStruture.php @@ -0,0 +1,26 @@ +wiki->services->get(TripleStore::class); + $pageManager = $this->wiki->services->get(PageManager::class); + $listManager = $this->wiki->services->get(ListManager::class); + $lists = $tripleStore->getMatching(null, TripleStore::TYPE_URI, ListManager::TRIPLES_LIST_ID, '', ''); + foreach ($lists as $list) { + $tag = $list['resource']; + $page = $pageManager->getOne($tag); + $oldJson = json_decode($page['body'], true); + $newJson = $listManager->convertDataStructure($oldJson); + $pageManager->save($tag, json_encode($newJson)); + } + } +} \ No newline at end of file diff --git a/tools/bazar/controllers/ListController.php b/tools/bazar/controllers/ListController.php index 1f0e44553..9bd3958f3 100644 --- a/tools/bazar/controllers/ListController.php +++ b/tools/bazar/controllers/ListController.php @@ -23,23 +23,21 @@ public function displayAll() if (isset($_POST['imported-list'])) { foreach ($_POST['imported-list'] as $listRaw) { $list = json_decode($listRaw, true); - $this->listManager->create($list['titre_liste'], $list['label']); + $this->listManager->create($list['title'], $list['nodes']); } echo '
' . _t('BAZ_LIST_IMPORT_SUCCESSFULL') . '.
'; + echo '
' . _t('BAZ_LIST_IMPORT_SUCCESSFULL') . '.
'; } $lists = $this->listManager->getAll(); - $values = []; foreach ($lists as $key => $list) { - $values[$key]['title'] = $list['titre_liste']; - $values[$key]['options'] = $list['label']; - $values[$key]['canEdit'] = !$this->securityController->isWikiHibernated() && $this->wiki->HasAccess('write', $key); - $values[$key]['canDelete'] = !$this->securityController->isWikiHibernated() && ($this->wiki->UserIsAdmin() || $this->wiki->UserIsOwner($key)); + $lists[$key]['canEdit'] = !$this->securityController->isWikiHibernated() && $this->wiki->HasAccess('write', $key); + $lists[$key]['canDelete'] = !$this->securityController->isWikiHibernated() && ($this->wiki->UserIsAdmin() || $this->wiki->UserIsOwner($key)); } return $this->render('@bazar/lists/list_table.twig', [ - 'lists' => $values, + 'lists' => $lists, 'loggedUser' => $this->wiki->GetUser(), 'canCreate' => !$this->securityController->isWikiHibernated(), ]); @@ -49,19 +47,19 @@ public function create() { if (isset($_POST['valider'])) { $i = 1; - $values = []; + $nodes = []; foreach ($_POST['label'] as $label) { if (($label != null || $label != '') && ($_POST['id'][$i] != null || $_POST['id'][$i] != '')) { - $values[$_POST['id'][$i]] = $label; + $nodes[] = ['id' => $_POST['id'][$i], 'label' => $label]; $i++; } } - $listeId = $this->listManager->create($_POST['titre_liste'], $values); + $listeId = $this->listManager->create($_POST['title'], $nodes); if ($this->shouldPostMessageOnSubmit()) { return $this->render('@core/iframe_result.twig', [ - 'data' => ['msg' => 'list_created', 'id' => $listeId, 'title' => $_POST['titre_liste']], + 'data' => ['msg' => 'list_created', 'id' => $listeId, 'title' => $_POST['title']], ]); } @@ -85,20 +83,20 @@ public function update($id) if (isset($_POST['valider'])) { if ($this->wiki->HasAccess('write', $id)) { $i = 1; - $values = []; + $nodes = []; foreach ($_POST['label'] as $label) { if (($label != null || $label != '') && ($_POST['id'][$i] != null || $_POST['id'][$i] != '')) { - $values[$_POST['id'][$i]] = $label; + $nodes[] = ['id' => $_POST['id'][$i], 'label' => $label]; } $i++; } - $this->listManager->update($id, $_POST['titre_liste'], $values); + $this->listManager->update($id, $_POST['title'], $nodes); if ($this->shouldPostMessageOnSubmit()) { return $this->render('@core/iframe_result.twig', [ - 'data' => ['msg' => 'list_updated', 'id' => $id, 'title' => $_POST['titre_liste']], + 'data' => ['msg' => 'list_updated', 'id' => $id, 'title' => $_POST['title']], ]); } @@ -111,9 +109,7 @@ public function update($id) } return $this->render('@bazar/lists/list_form.twig', [ - 'listId' => $id, - 'title' => $list['titre_liste'], - 'labels' => $list['label'], + 'list' => $list, ]); } diff --git a/tools/bazar/fields/EnumField.php b/tools/bazar/fields/EnumField.php index 80b2e866b..5dc42e699 100644 --- a/tools/bazar/fields/EnumField.php +++ b/tools/bazar/fields/EnumField.php @@ -39,9 +39,12 @@ public function __construct(array $values, ContainerInterface $services) public function loadOptionsFromList() { if (!empty($this->getLinkedObjectName())) { - $listValues = $this->getService(ListManager::class)->getOne($this->getLinkedObjectName()); - if (is_array($listValues)) { - $this->options = $listValues['label']; + $list = $this->getService(ListManager::class)->getOne($this->getLinkedObjectName()); + if (isset($list['nodes'])) { + $this->options = array_reduce($list['nodes'], function ($acc, $node) { + $acc[$node['id']] = $node['label']; + return $acc; + }, []); } } } @@ -85,13 +88,11 @@ protected function loadOptionsFromJSONForm($JSONAddress): array // be carefull it is an array here if (isset($field['propertyname']) && ($field['propertyname'] == $this->getPropertyName())) { $this->options = $field['options'] ?? []; - return $this->options; } } } $this->options = []; - return $this->options; } @@ -139,12 +140,14 @@ protected function prepareJSONEntryField() { $this->propertyName = $this->type . removeAccents(preg_replace('/--+/u', '-', preg_replace('/[[:punct:]]/', '-', $this->name))) . $this->listLabel; $this->loadOptionsFromJson(); - if (preg_match('/^(.*\/\??)'// catch baseUrl + if ( + preg_match('/^(.*\/\??)'// catch baseUrl . '(?:' // followed by . '\w*\/json&(?:.*)demand=entries(?:&.*)?' // json handler with demand = entries . '|api\/forms\/[0-9]*\/entries' // or api forms/{id}/entries . '|api\/entries\/[0-9]*' // or api entries/{id} - . ')/', $this->name, $matches)) { + . ')/', $this->name, $matches) + ) { $this->baseUrl = $matches[1]; } else { $this->baseUrl = $this->name; @@ -167,7 +170,6 @@ protected function getEntriesOptions() $this->loadOptionsFromEntries(); } } - return $this->options; } @@ -233,4 +235,4 @@ private function sanitizeUrlForEntries(string $url): string return $url; } -} +} \ No newline at end of file diff --git a/tools/bazar/libs/bazar.edit_lists.js b/tools/bazar/libs/bazar.edit_lists.js index a709da39b..cc50dada6 100755 --- a/tools/bazar/libs/bazar.edit_lists.js +++ b/tools/bazar/libs/bazar.edit_lists.js @@ -81,46 +81,77 @@ $(document).ready(() => { // on formate l url pour acceder au service json de yeswiki const taburl = url.split('wakka.php') url = `${taburl[0].replace(/\/+$/g, '')}/wakka.php?wiki=BazaR/json&demand=lists` - resultimportlist.html(`
${listtranslations.loading}... ${listtranslations.recuperation} ${url}
`) + resultimportlist.html(`
+ ${listtranslations.loading}... + ${listtranslations.recuperation} ${url} +
`) + $.ajax({ method: 'GET', url }).done((data) => { resultimportlist.html('') let count = 0 - for (var idlist in data) { - if (data.hasOwnProperty(idlist)) { - count++ - let select = `` - for (const key in data[idlist].label) { - if (data[idlist].label.hasOwnProperty(key)) { - select += `` - } - } - let trclass = '' - let existingmessage = '' - if (existinglists.find('td').filter(function() { - return $(this).text() === idlist - }).length > 0) { - trclass = ' class="error danger"' - existingmessage = `
${listtranslations.existingmessage}` + Object.entries(data).forEach(([idlist, listData]) => { + count += 1 + let list = {} + + // Convert old data structure + if (listData.titre_liste) { + list = { + title: listData.titre_liste, + nodes: [] } + Object.entries(listData.label).forEach(([id, label]) => { + list.nodes.push({ id, label, children: [] }) + }) + } else { + list = listData + } - let tablerow = `` + let select = `` + list.nodes.forEach((node) => { + select += `` + }) - tablerow += `${idlist + existingmessage}${data[idlist].titre_liste}` - resultimporttable.find('tbody').append(tablerow) + let trclass = '' + let existingmessage = '' + if (existinglists.find('td').filter(function() { + return $(this).text() === idlist + }).length > 0) { + trclass = ' class="error danger"' + existingmessage = `
+ ${listtranslations.existingmessage}` } - } + + resultimporttable.find('tbody').append( + ` + + + + ${idlist + existingmessage} + ${list.title} + + ` + ) + }) resultimportform.removeClass('hide') - resultimportlist.prepend(`
${listtranslations.nblistsfound} : ${count}
`) - }).fail((jqXHR, textStatus, errorThrown) => { + resultimportlist.prepend(`
+ ${listtranslations.nblistsfound} : ${count} +
`) + }).fail(() => { resultimportlist.html(`
${listtranslations.noanswers}.
`) }) } else { - resultimportlist.html(`
${listtranslations.notvalidurl} : ${url}
`) + resultimportlist.html(`
+ ${listtranslations.notvalidurl} : ${url} +
`) } }) }) diff --git a/tools/bazar/libs/bazar.fonct.php b/tools/bazar/libs/bazar.fonct.php index 8eb3dfd9f..fc1db0dba 100755 --- a/tools/bazar/libs/bazar.fonct.php +++ b/tools/bazar/libs/bazar.fonct.php @@ -5,6 +5,7 @@ use YesWiki\Bazar\Field\EnumField; use YesWiki\Bazar\Service\EntryManager; use YesWiki\Bazar\Service\FormManager; +use YesWiki\Bazar\Service\ListManager; function multiArraySearch($array, $key, $value) { @@ -25,10 +26,10 @@ function multiArraySearch($array, $key, $value) function baz_forms_and_lists_ids() { - foreach (baz_valeurs_liste() as $listId => $list) { - $lists[$listId] = $list['titre_liste']; - } - + $lists = $GLOBALS['wiki']->services->get(ListManager::class)->getAll(); + $lists = array_map(function ($list) { + return $list['title']; + }, $lists); $requete = 'SELECT bn_id_nature, bn_label_nature FROM ' . $GLOBALS['wiki']->config['table_prefix'] . 'nature'; $result = $GLOBALS['wiki']->LoadAll($requete); foreach ($result as $form) { @@ -45,36 +46,39 @@ function getHtmlDataAttributes($fiche, $formtab = '') $form = isset($formtab[$fiche['id_typeannonce']]) ? $formtab[$fiche['id_typeannonce']] : $GLOBALS['wiki']->services->get(FormManager::class)->getOne($fiche['id_typeannonce']); foreach ($fiche as $key => $value) { if (!empty($value)) { - if (in_array( - $key, - [ - 'bf_latitude', - 'bf_longitude', - 'id_typeannonce', - 'owner', - 'date_creation_fiche', - 'date_debut_validite_fiche', - 'date_fin_validite_fiche', - 'id_fiche', - 'statut_fiche', - 'date_maj_fiche', - ] - )) { + if ( + in_array( + $key, + [ + 'bf_latitude', + 'bf_longitude', + 'id_typeannonce', + 'owner', + 'date_creation_fiche', + 'date_debut_validite_fiche', + 'date_fin_validite_fiche', + 'id_fiche', + 'statut_fiche', + 'date_maj_fiche', + ] + ) + ) { $htmldata .= - 'data-' . htmlspecialchars($key) . '="' . - htmlspecialchars($value) . '" '; + 'data-' . htmlspecialchars($key) . '="' . + htmlspecialchars($value) . '" '; } else { if (isset($form['prepared'])) { foreach ($form['prepared'] as $field) { $propertyName = $field->getPropertyName(); if ($propertyName === $key) { - if ($field instanceof EnumField + if ( + $field instanceof EnumField || $field instanceof DateField || $field->getName() == 'scope' ) { $htmldata .= - 'data-' . htmlspecialchars($key) . '="' . - htmlspecialchars(is_array($value) ? '[' . implode(',', $value) . ']' : $value) . '" '; + 'data-' . htmlspecialchars($key) . '="' . + htmlspecialchars(is_array($value) ? '[' . implode(',', $value) . ']' : $value) . '" '; } } } diff --git a/tools/bazar/services/ListManager.php b/tools/bazar/services/ListManager.php index da74fc908..2daa0cc22 100644 --- a/tools/bazar/services/ListManager.php +++ b/tools/bazar/services/ListManager.php @@ -57,17 +57,27 @@ public function getOne($id): ?array $page = $this->pageManager->getOne($id); $json = json_decode($page['body'], true); + $json = $this->convertDataStructure($json); + $json['id'] = $id; + $this->cachedLists[$id] = $json; - if (YW_CHARSET !== 'UTF-8') { - $this->cachedLists[$id]['titre_liste'] = mb_convert_encoding($json['titre_liste'], 'ISO-8859-1', 'UTF-8'); - $this->cachedLists[$id]['label'] = array_map(function ($value) { - return mb_convert_encoding($value, 'ISO-8859-1', 'UTF-8'); - }, $json['label']); - } else { - $this->cachedLists[$id] = $json; - } + return $json; + } - return $this->cachedLists[$id]; + // The structure of List object has been changed in 2024 + // Convert old List { titre_liste: "My List", label: { id1: "first Key", id2: "second id" } } + // to { title: "My List", values: [{ id: "id1", label: "first id"}, { id: "id2", label: "second id"}]} + // We still convert the strucure on the fly in case the migration went wrong + public function convertDataStructure($json) + { + if (isset($json['titre_liste'])) { + $newJson = ['title' => $json['titre_liste'], 'nodes' => []]; + foreach ($json['label'] as $id => $label) { + $newJson['nodes'][] = ['id' => $id, 'label' => $label]; + } + return $newJson; + } + return $json; } public function getAll(): array @@ -82,25 +92,16 @@ public function getAll(): array return $result; } - public function create($title, $values) + public function create($title, $nodes) { if ($this->securityController->isWikiHibernated()) { throw new \Exception(_t('WIKI_IN_HIBERNATION')); } - $id = genere_nom_wiki('Liste ' . $title); - - $values = $this->sanitizeHMTL($values); - - if (YW_CHARSET !== 'UTF-8') { - $values = array_map(function ($value) { - return mb_convert_encoding($value, 'UTF-8', 'ISO-8859-1'); - }, $values); - $title = mb_convert_encoding($title, 'UTF-8', 'ISO-8859-1'); - } + $id = genere_nom_wiki('List' . $title); $this->pageManager->save($id, json_encode([ - 'titre_liste' => $title, - 'label' => $values, + 'title' => $title, + 'nodes' => $this->sanitizeHMTL($nodes) ])); $this->tripleStore->create($id, TripleStore::TYPE_URI, self::TRIPLES_LIST_ID, '', ''); @@ -108,23 +109,15 @@ public function create($title, $values) return $id; } - public function update($id, $title, $values) + public function update($id, $title, $nodes) { if ($this->securityController->isWikiHibernated()) { throw new \Exception(_t('WIKI_IN_HIBERNATION')); } - $values = $this->sanitizeHMTL($values); - if (YW_CHARSET !== 'UTF-8') { - $values = array_map(function ($value) { - return mb_convert_encoding($value, 'UTF-8', 'ISO-8859-1'); - }, $values); - $title = mb_convert_encoding($title, 'UTF-8', 'ISO-8859-1'); - } - $this->pageManager->save($id, json_encode([ - 'titre_liste' => $title, - 'label' => $values, + 'title' => $title, + 'nodes' => $this->sanitizeHMTL($nodes) ])); } @@ -146,10 +139,11 @@ public function delete($id) $this->tripleStore->delete($id, TripleStore::TYPE_URI, null, '', ''); } - private function sanitizeHMTL(array $values) + private function sanitizeHMTL(array $nodes) { return array_map(function ($value) { - return $this->htmlPurifierService->cleanHTML($value); - }, $values); + $value['label'] = $this->htmlPurifierService->cleanHTML($value['label']); + return $value; + }, $nodes); } -} +} \ No newline at end of file diff --git a/tools/bazar/templates/lists/list_form.twig b/tools/bazar/templates/lists/list_form.twig index 79190476f..00fddf043 100755 --- a/tools/bazar/templates/lists/list_form.twig +++ b/tools/bazar/templates/lists/list_form.twig @@ -14,9 +14,9 @@
From 6069864cbf6237d05bc2977f9af08f1b09dcb4ce Mon Sep 17 00:00:00 2001 From: Sebastian Castro Date: Tue, 2 Jul 2024 18:39:29 +0000 Subject: [PATCH 08/42] Fix list import checkbox width --- tools/bazar/templates/lists/list_table.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/bazar/templates/lists/list_table.twig b/tools/bazar/templates/lists/list_table.twig index 63b6aa991..c04e03d3a 100644 --- a/tools/bazar/templates/lists/list_table.twig +++ b/tools/bazar/templates/lists/list_table.twig @@ -84,7 +84,7 @@ -
+