diff --git a/.editorconfig b/.editorconfig
index 9f62084fe..5ec095c88 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -13,4 +13,4 @@ indent_size = 4
[*.{html,js,json}]
indent_style = space
-indent_size = 2
\ No newline at end of file
+indent_size = 2
diff --git a/.phpactor.json b/.phpactor.json
index 014b6a372..29a055dcf 100644
--- a/.phpactor.json
+++ b/.phpactor.json
@@ -1,3 +1,4 @@
{
"$schema": "/phpactor.schema.json",
"language_server_php_cs_fixer.enabled": true
+}
diff --git a/docs/actions/lang/actionsbuilder_en.inc.php b/docs/actions/lang/actionsbuilder_en.inc.php
index c39621e1d..c1f4db919 100644
--- a/docs/actions/lang/actionsbuilder_en.inc.php
+++ b/docs/actions/lang/actionsbuilder_en.inc.php
@@ -565,7 +565,7 @@
'AB_buttons_action_button_pull_right' => 'Right',
'AB_attach_link_label' => 'Associated link',
'AB_attach_caption_label' => 'Text displayed on hovering',
- 'AB_attach_nofullimagelink_label' => 'Add a link to only display the full image',
+ 'AB_attach_nofullimagelink_label' => 'Enable to click on the image to display the full image',
'AB_attach_class_position_left' => 'Left',
'AB_attach_class_position_center' => 'Center',
'AB_attach_class_position_right' => 'Right',
diff --git a/handlers/DuplicateHandler.php b/handlers/DuplicateHandler.php
index 1e0f8bd3b..c3829555d 100644
--- a/handlers/DuplicateHandler.php
+++ b/handlers/DuplicateHandler.php
@@ -2,6 +2,7 @@
use YesWiki\Bazar\Controller\EntryController;
use YesWiki\Bazar\Service\EntryManager;
+use YesWiki\Bazar\Service\FormManager;
use YesWiki\Bazar\Service\ListManager;
use YesWiki\Core\Controller\AuthController;
use YesWiki\Core\Service\AclService;
@@ -33,9 +34,9 @@ public function run()
]);
} elseif (!$this->getService(AclService::class)->hasAccess('read', $this->wiki->GetPageTag())) {
// if no read access to the page
- if ($contenu = $this->getService(PageManager::class)->getOne('PageLogin')) {
+ if ($content = $this->getService(PageManager::class)->getOne('PageLogin')) {
// si une page PageLogin existe, on l'affiche
- $error .= $this->wiki->Format($contenu['body']);
+ $error .= $this->wiki->Format($content['body']);
} else {
// sinon on affiche le formulaire d'identification minimal
$error .= '
' . "\n"
@@ -50,7 +51,7 @@ public function run()
$data = $this->duplicationManager->checkPostData($_POST);
$this->duplicationManager->duplicateLocally($data);
if ($data['duplicate-action'] == 'edit') {
- $this->wiki->Redirect($this->wiki->href('edit', $data['pageTag']));
+ $this->wiki->Redirect($this->wiki->href('edit', $data['newTag']));
return;
} elseif ($data['duplicate-action'] == 'return') {
@@ -58,10 +59,10 @@ public function run()
return;
}
- $this->wiki->Redirect($this->wiki->href('', $data['pageTag']));
+ $this->wiki->Redirect($this->wiki->href('', $data['newTag']));
return;
- } catch (\Throwable $th) {
+ } catch (Throwable $th) {
$error .= $this->render('@templates\alert-message-with-back.twig', [
'type' => 'warning',
'message' => $th->getMessage(),
@@ -79,23 +80,24 @@ public function run()
$pageTitle = '';
if ($isEntry) {
$title = _t('TEMPLATE_DUPLICATE_ENTRY') . ' ' . $this->wiki->GetPageTag();
- $pageContent = $this->getService(EntryManager::class)->getOne($this->wiki->GetPageTag());
+ $originalContent = $this->getService(EntryManager::class)->getOne($this->wiki->GetPageTag());
if ($toExternalWiki) {
- $pageTitle = $pageContent['bf_titre'];
+ $pageTitle = $originalContent['bf_titre'];
$proposedTag = $this->wiki->GetPageTag();
- $pageContent = $this->wiki->page['body'];
+ $originalContent = $this->wiki->page['body'];
+ $form = $this->getService(FormManager::class)->getOne($this->getService(EntryManager::class)->getOne($proposedTag)['id_typeannonce']);
} else {
- $pageTitle = $pageContent['bf_titre'] . ' (' . _t('DUPLICATE') . ')';
+ $pageTitle = $originalContent['bf_titre'] . ' (' . _t('DUPLICATE') . ')';
$proposedTag = genere_nom_wiki($pageTitle);
}
} elseif ($isList) {
$title = _t('TEMPLATE_DUPLICATE_LIST') . ' ' . $this->wiki->GetPageTag();
- $pageContent = $this->getService(ListManager::class)->getOne($this->wiki->GetPageTag());
+ $originalContent = $this->getService(ListManager::class)->getOne($this->wiki->GetPageTag());
if ($toExternalWiki) {
- $pageTitle = $pageContent['titre_liste'];
+ $pageTitle = $originalContent['titre_liste'];
$proposedTag = $this->wiki->GetPageTag();
} else {
- $pageTitle = $pageContent['titre_liste'] . ' (' . _t('DUPLICATE') . ')';
+ $pageTitle = $originalContent['titre_liste'] . ' (' . _t('DUPLICATE') . ')';
$proposedTag = genere_nom_wiki('Liste ' . $pageTitle);
}
} else { // page
@@ -105,7 +107,7 @@ public function run()
} else {
$proposedTag = genere_nom_wiki($this->wiki->GetPageTag() . ' ' . _t('DUPLICATE'));
}
- $pageContent = $this->wiki->page['body'];
+ $originalContent = $this->wiki->page['body'];
}
$attachments = $this->duplicationManager->findFiles($this->wiki->page['tag']);
$totalSize = 0;
@@ -130,9 +132,10 @@ public function run()
'proposedTag' => $proposedTag ?? '',
'attachments' => $attachments ?? [],
'pageTitle' => $pageTitle ?? '',
- 'pageContent' => $pageContent ?? '',
+ 'originalContent' => $originalContent ?? '',
'totalSize' => $this->duplicationManager->humanFilesize($totalSize ?? 0),
'type' => $type ?? '',
+ 'form' => $form ?? '',
'baseUrl' => preg_replace('/\?$/Ui', '', $this->wiki->config['base_url']),
'toExternalWiki' => $toExternalWiki,
]);
diff --git a/includes/services/DuplicationManager.php b/includes/services/DuplicationManager.php
index 1a7396b73..053bc7bc1 100644
--- a/includes/services/DuplicationManager.php
+++ b/includes/services/DuplicationManager.php
@@ -56,7 +56,7 @@ private function getLocalFileUploadPath()
*
* @return array keys of fields that may contain attachments to import
*/
- public function getUploadFieldsFromEntry($id)
+ private function getUploadFieldsFromEntry($id)
{
$fields = [];
$entry = $this->wiki->services->get(EntryManager::class)->getOne($id);
@@ -65,11 +65,8 @@ public function getUploadFieldsFromEntry($id)
$form = $formManager->getOne($entry['id_typeannonce']);
// find fields that are textareas
foreach ($form['prepared'] as $field) {
- if ($field instanceof TextareaField or $field instanceof ImageField or $field instanceof FileField) {
- $fields[] = [
- 'id' => $field->getPropertyName(),
- 'type' => $field->getType(),
- ];
+ if ($field instanceof TextareaField || $field instanceof ImageField || $field instanceof FileField) {
+ $fields[] = $field;
}
}
}
@@ -77,7 +74,7 @@ public function getUploadFieldsFromEntry($id)
return $fields;
}
- public function findFilesInUploadField($fieldValue)
+ private function findFilesInUploadField($fieldValue)
{
$f = $this->uploadPath . '/' . $fieldValue;
if ($f !== $this->uploadPath . '/' && file_exists($f)) {
@@ -98,7 +95,7 @@ public function findFilesInUploadField($fieldValue)
*
* @return array files
*/
- public function findFilesInWikiText($tag, $wikiText)
+ private function findFilesInWikiText($tag, $wikiText)
{
$filesMatched = [];
$regex = '#\{\{attach.*file="(.*)".*\}\}#Ui';
@@ -149,7 +146,7 @@ public function findFilesInWikiText($tag, $wikiText)
}
/**
- * Get file attachements from pageTag.
+ * Get file attachements from newTag.
*
* @param string $tag page id
*
@@ -166,12 +163,12 @@ public function findFiles($tag = '')
$fields = $this->getUploadFieldsFromEntry($tag);
$entry = $this->wiki->services->get(EntryManager::class)->getOne($tag);
foreach ($fields as $f) {
- if ($f['type'] == 'image' || $f['type'] == 'fichier') {
- if (!empty($fi = $this->findFilesInUploadField($entry[$f['id']]))) {
+ if ($f instanceof ImageField || $f instanceof FileField) {
+ if (!empty($fi = $this->findFilesInUploadField($entry[$f->getPropertyName()]))) {
$files[] = $fi;
}
- } elseif ($f['type'] == 'textelong') {
- if (!empty($fi = $this->findFilesInWikiText($tag, $entry[$f['id']]))) {
+ } elseif ($f instanceof TextareaField) {
+ if (!empty($fi = $this->findFilesInWikiText($tag, $entry[$f->getPropertyName()]))) {
$files = array_merge($files, $fi);
}
}
@@ -212,21 +209,21 @@ public function duplicateFiles($fromTag, $toTag)
public function checkPostData($data)
{
- if (empty($data['type']) || !in_array($data['type'], ['page', 'list', 'entry'])) {
+ if (empty($data['type']) || !in_array($data['type'], ['form', 'page', 'list', 'entry'])) {
throw new \Exception(_t('NO_VALID_DATA_TYPE'));
}
- if (empty($data['pageTag'])) {
+ if (empty($data['newTag'])) {
throw new \Exception(_t('EMPTY_PAGE_TAG'));
}
- if ($data['type'] != 'page' && empty($data['pageTitle'])) {
+ if ($data['type'] != 'page' && empty($data['newTitle'])) {
throw new \Exception(_t('EMPTY_PAGE_TITLE'));
}
if (!$this->wiki->UserIsAdmin()) {
throw new \Exception(_t('ONLY_ADMINS_CAN_DUPLICATE') . '.');
}
- $page = $this->wiki->services->get(PageManager::class)->getOne($data['pageTag']);
+ $page = $this->wiki->services->get(PageManager::class)->getOne($data['newTag']);
if ($page) {
- throw new \Exception($data['pageTag'] . ' ' . _t('ALREADY_EXISTING'));
+ throw new \Exception($data['newTag'] . ' ' . _t('ALREADY_EXISTING'));
}
if (empty($data['duplicate-action']) || !in_array($data['duplicate-action'], ['open', 'edit', 'return'])) {
throw new \Exception(_t('NO_DUPLICATE_ACTION') . '.');
@@ -242,21 +239,21 @@ public function duplicateLocally($data)
}
switch ($data['type']) {
case 'list':
- $list = $this->wiki->services->get(ListManager::class)->getOne($this->wiki->getPageTag());
- $this->wiki->services->get(ListManager::class)->create($data['pageTitle'], $list['label'], $data['pageTag']);
+ $list = $this->wiki->services->get(ListManager::class)->getOne($data['originalTag']);
+ $this->wiki->services->get(ListManager::class)->create($data['newTitle'], $list['label'], $data['newTag']);
break;
case 'entry':
- $files = $this->duplicateFiles($this->wiki->getPageTag(), $data['pageTag']);
+ $files = $this->duplicateFiles($data['originalTag'], $data['newTag']);
$entry = $this->wiki->services->get(EntryManager::class)->getOne($this->wiki->getPageTag());
$fields = $this->getUploadFieldsFromEntry($this->wiki->GetPageTag());
foreach ($fields as $f) {
foreach ($files as $fi) {
- $entry[$f['id']] = str_replace($fi['originalFile'], $fi['duplicatedFile'], $entry[$f['id']]);
+ $entry[$f->getPropertyName()] = str_replace($fi['originalFile'], $fi['duplicatedFile'], $entry[$f->getPropertyName()]);
}
}
- $entry['id_fiche'] = $data['pageTag'];
- $entry['bf_titre'] = $data['pageTitle'];
+ $entry['id_fiche'] = $data['newTag'];
+ $entry['bf_titre'] = $data['newTitle'];
$entry['antispam'] = 1;
$this->wiki->services->get(EntryManager::class)->create($entry['id_typeannonce'], $entry);
break;
@@ -264,11 +261,11 @@ public function duplicateLocally($data)
default:
case 'page':
$newBody = $this->wiki->page['body'];
- $files = $this->duplicateFiles($this->wiki->getPageTag(), $data['pageTag']);
+ $files = $this->duplicateFiles($data['originalTag'], $data['newTag']);
foreach ($files as $f) {
$newBody = str_replace($f['originalFile'], $f['duplicatedFile'], $newBody);
}
- $this->wiki->services->get(PageManager::class)->save($data['pageTag'], $newBody);
+ $this->wiki->services->get(PageManager::class)->save($data['newTag'], $newBody);
break;
}
@@ -280,7 +277,7 @@ public function duplicateLocally($data)
);
$this->wiki->services->get(AclService::class)->save(
- $data['pageTag'],
+ $data['newTag'],
$privilege,
$values['list']
);
@@ -292,9 +289,9 @@ public function duplicateLocally($data)
'http://outils-reseaux.org/_vocabulary/tag',
];
foreach ($properties as $prop) {
- $values = $this->wiki->services->get(TripleStore::class)->getAll($this->wiki->GetPageTag(), $prop, '', '');
+ $values = $this->wiki->services->get(TripleStore::class)->getAll($data['originalTag'], $prop, '', '');
foreach ($values as $val) {
- $this->wiki->services->get(TripleStore::class)->create($data['pageTag'], $prop, $val['value'], '', '');
+ $this->wiki->services->get(TripleStore::class)->create($data['newTag'], $prop, $val['value'], '', '');
}
}
}
@@ -303,15 +300,11 @@ public function importDistantContent($tag, $request)
{
if ($this->wiki->services->get(PageManager::class)->getOne($tag)) {
throw new Exception(_t('ACEDITOR_LINK_PAGE_ALREADY_EXISTS'));
-
- return;
}
$req = $request->request->all();
- foreach (['pageContent', 'sourceUrl', 'originalTag', 'type'] as $key) {
+ foreach (['originalContent', 'sourceUrl', 'originalTag', 'type'] as $key) {
if (empty($req[$key])) {
throw new Exception(_t('NOT_FOUND_IN_REQUEST', $key));
-
- return;
}
}
foreach ($req['files'] as $fileUrl) {
@@ -319,14 +312,14 @@ public function importDistantContent($tag, $request)
}
$newUrl = explode('/?', $this->wiki->config['base_url'])[0];
- $newBody = str_replace($req['sourceUrl'], $newUrl, $req['pageContent']);
+ $newBody = str_replace($req['sourceUrl'], $newUrl, $req['originalContent']);
if ($req['type'] === 'page') {
$this->wiki->services->get(PageManager::class)->save($tag, $newBody);
} elseif ($req['type'] === 'entry') {
$entry = json_decode($newBody, true);
$entry['id_fiche'] = $tag;
$entry['antispam'] = 1;
- $this->wiki->services->get(EntryManager::class)->create($entry['id_typeannonce'], $entry);
+ $this->wiki->services->get(EntryManager::class)->create($entry['id_typeannonce'], $entry, false, $req['sourceUrl']);
}
}
diff --git a/index.php b/index.php
index b9c524a7a..8b2fe5c16 100755
--- a/index.php
+++ b/index.php
@@ -8,9 +8,9 @@
*
* @category Wiki
*
- * @license GNU/GPL version 3
+ * @license GNU/GPL version 3
*
- * @see https://yeswiki.net
+ * @see https://yeswiki.net
*/
use YesWiki\Core\YesWikiLoader;
diff --git a/javascripts/handlers/duplicate.js b/javascripts/handlers/duplicate.js
index 5d690d917..8dbeb7cae 100644
--- a/javascripts/handlers/duplicate.js
+++ b/javascripts/handlers/duplicate.js
@@ -9,15 +9,19 @@ function isValidUrl(string) {
}
}
+function arrayIncludesAllRequiredFields(arr, fields) {
+ return fields.every((v) => arr.some((i) => i.id === v.id && i.type === v.type))
+}
+
function blockDuplicationName(tag) {
$('[name=duplicate-action]').attr('disabled', 'disabled').addClass('disabled')
- $('#pageTag').parents('.form-group').removeClass('has-success').addClass('has-error')
+ $('#newTag').parents('.form-group').removeClass('has-success').addClass('has-error')
$('#pagetag-message').html(_t('PAGE_NOT_AVAILABLE', { tag }))
}
function validateDuplicationName(tag) {
$('[name=duplicate-action]').removeAttr('disabled').removeClass('disabled')
- $('#pageTag').parents('.form-group').removeClass('has-error').addClass('has-success')
+ $('#newTag').parents('.form-group').removeClass('has-error').addClass('has-success')
$('#pagetag-message').html(_t('PAGE_AVAILABLE', { tag }))
}
@@ -43,7 +47,7 @@ function handleLoginResponse(data) {
.addClass('has-success')
$('.login-fields').addClass('hide')
$('.duplication-fields').removeClass('hide')
- checkPageExistence(`${shortUrl}/?api/pages/${$('#pageTag').val()}`)
+ checkPageExistence(`${shortUrl}/?api/pages/${$('#newTag').val()}`)
} else {
$('#login-message').html(_t('CONNECTED_BUT_NOT_ADMIN', { user: data.user })).parents('.form-group')
.removeClass('has-success')
@@ -58,7 +62,7 @@ document.addEventListener('DOMContentLoaded', () => {
e.stopPropagation()
return false
})
- $('#urlWiki').on('change', () => {
+ $('#url-wiki').on('change', () => {
$('.login-fields, .duplication-fields').addClass('hide')
$('#login-message').html('')
})
@@ -84,19 +88,19 @@ document.addEventListener('DOMContentLoaded', () => {
})
$('[name="duplicate-action"]').on('click', (e) => {
- var btnAction = e.currentTarget.value
+ const btnAction = e.currentTarget.value
$.ajax({
method: 'POST',
- url: `${shortUrl}/?api/pages/${$('#pageTag').val()}/duplicate`,
+ url: `${shortUrl}/?api/pages/${$('#newTag').val()}/duplicate`,
data: $('#form-duplication').serialize()
- }).done((data) => {
- if (btnAction == 'open') {
- location = `${shortUrl}/?${data.pageTag}`
- } else if (btnAction == 'edit') {
- location = `${shortUrl}/?${data.pageTag}/edit`
+ }).done((d) => {
+ if (btnAction === 'open') {
+ document.location = `${shortUrl}/?${d.newTag}`
+ } else if (btnAction === 'edit') {
+ document.location = `${shortUrl}/?${d.newTag}/edit`
} else {
- let url = location.href.replace(/\/duplicate.*/, '')
- location = url
+ const url = document.location.href.replace(/\/duplicate.*/, '')
+ document.location = url
}
}).fail((jqXHR) => {
toastMessage(`${_t('ERROR')} ${jqXHR.status}`, 3000, 'alert alert-danger')
@@ -105,11 +109,11 @@ document.addEventListener('DOMContentLoaded', () => {
})
$('.btn-verify-tag').on('click', () => {
- checkPageExistence(`${shortUrl}/?api/pages/${$('#pageTag').val()}`)
+ checkPageExistence(`${shortUrl}/?api/pages/${$('#newTag').val()}`)
})
$('.btn-verify-wiki').on('click', () => {
- let url = $('#urlWiki').val()
+ let url = $('.duplication-wiki-form').find('#url-wiki').val()
if (isValidUrl(url)) {
let taburl = []
@@ -119,13 +123,40 @@ document.addEventListener('DOMContentLoaded', () => {
taburl = url.split('?')
}
shortUrl = taburl[0].replace(/\/+$/g, '')
- $('#baseUrl').text(`${shortUrl}/?`)
+ $('#base-url').text(`${shortUrl}/?`)
url = `${shortUrl}/?api/auth/me`
$.ajax({
method: 'GET',
url
}).done((data) => {
handleLoginResponse(data)
+
+ // if case of entry, we need to check if form id is available and compatible
+ // or propose another id
+ const formId = $('#form-id').val()
+ if (typeof formId !== 'undefined') {
+ const formUrl = `${shortUrl}/?api/forms/${formId}`
+ $.ajax({
+ method: 'GET',
+ url: formUrl
+ }).done((form) => {
+ const requiredFields = form.prepared.filter((field) => field.required === true)
+ // we check if the found formId is compatible
+ if (arrayIncludesAllRequiredFields(window.sourceForm.prepared, requiredFields)) {
+ $('#form-message').removeClass('has-error').addClass('has-success').find('.help-block')
+ .html(_t('FORM_ID_IS_COMPATIBLE', { id: formId }))
+ } else {
+ $('#form-message').removeClass('has-success').addClass('has-error').find('.help-block')
+ .html(_t('FORM_ID_NOT_AVAILABLE', { id: formId }))
+ }
+ }).fail((jqXHR) => {
+ if (jqXHR.status === 404) {
+ // the formId is available
+ $('#form-message').removeClass('has-error').addClass('has-success').find('.help-block')
+ .html(_t('FORM_ID_AVAILABLE', { id: formId }))
+ }
+ })
+ }
}).fail((jqXHR) => {
if (jqXHR.status === 401) {
$('#login-message').html(`
${_t('NOT_CONNECTED')}
`)
@@ -138,4 +169,4 @@ document.addEventListener('DOMContentLoaded', () => {
toastMessage(_t('NOT_VALID_URL', { url }), 3000, 'alert alert-danger')
}
})
-})
\ No newline at end of file
+})
diff --git a/javascripts/users-table.js b/javascripts/users-table.js
index 3dc85030a..2a458ff01 100644
--- a/javascripts/users-table.js
+++ b/javascripts/users-table.js
@@ -35,7 +35,7 @@ const usersTableService = {
''
]).draw()
if (userLink !== '') {
- $(`#users-table-link-change-password`).html("
"+_t('LINK_TO_CHANGE_PASSWORD')+" "+userLink+" ")
+ $('#users-table-link-change-password').html(`
${_t('LINK_TO_CHANGE_PASSWORD')} ${userLink} `)
}
toastMessage(_t('USERSTABLE_USER_CREATED', { name: userName }), 1100, 'alert alert-success')
},
diff --git a/javascripts/yeswiki-base.js b/javascripts/yeswiki-base.js
index 542fb9624..558d6ad7d 100755
--- a/javascripts/yeswiki-base.js
+++ b/javascripts/yeswiki-base.js
@@ -921,4 +921,4 @@ $('#yw-a11y-jump-content').click(() => {
setTimeout(() => {
$('#yw-topnav').removeClass('nav-down').addClass('nav-up')
}, 300)
-})
\ No newline at end of file
+})
diff --git a/lang/yeswikijs_fr.php b/lang/yeswikijs_fr.php
index c66bab516..59c4ccbe2 100644
--- a/lang/yeswikijs_fr.php
+++ b/lang/yeswikijs_fr.php
@@ -159,4 +159,7 @@
'CONNECTED_AS_ADMIN' => 'L\'utilisateurice {user} est bien connecté.e sur le YesWiki de destination, avec des droits d\'administration.',
'CONNECTED_BUT_NOT_ADMIN' => 'L\'utilisateurice {user} est bien connecté.e sur le YesWiki de destination, mais n\'a pas les droits d\'administration. Veuillez-vous connecter avec un compte admin.',
'NOT_WIKI_OR_OLD_WIKI' => 'Le site indiqué ne semble pas être un YesWiki, ou sa version est antérieure à 4.5.0',
+ 'FORM_ID_AVAILABLE' => 'Le formulaire avec l\'identifiant {id} n\'existant pas encore sur l\'url indiqué, il sera créé.',
+ 'FORM_ID_NOT_AVAILABLE' => 'Le formulaire avec l\'identifiant {id} n\'est plus disponible sur l\'url indiqué, il faut changer d\'identifiant.',
+ 'FORM_ID_IS_COMPATIBLE' => 'Un formulaire du même identifiant ({id}) existe sur l\'url indiqué et semble avoir au moins les champs obligatoires similaires. Il sera utilisé pour la duplication.',
];
diff --git a/templates/handlers/duplicate.twig b/templates/handlers/duplicate.twig
index 550499afe..f42d399a4 100644
--- a/templates/handlers/duplicate.twig
+++ b/templates/handlers/duplicate.twig
@@ -7,9 +7,9 @@
+ {% if form %}
+
+
+
+ {% endif %}
{# hide the field while not connected #}
{% endif %}