-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/duplication #1180
base: doryphore-dev
Are you sure you want to change the base?
Feat/duplication #1180
Changes from 16 commits
caa3a30
772c1a8
649a1f7
2f81288
5596396
041630f
13aa5c6
4b18051
a5b0869
2630656
fb02c12
8bb6841
5b4abc7
301df7f
94cb65d
c1b23a1
c599e51
84019bd
eba365d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
<?php | ||
|
||
use YesWiki\Core\Service\AclService; | ||
use YesWiki\Bazar\Controller\EntryController; | ||
use YesWiki\Bazar\Service\EntryManager; | ||
use YesWiki\Bazar\Service\ListManager; | ||
use YesWiki\Core\Service\PageManager; | ||
use YesWiki\Core\Service\DuplicationManager; | ||
use YesWiki\Core\Controller\AuthController; | ||
use YesWiki\Core\YesWikiHandler; | ||
|
||
class DuplicateHandler extends YesWikiHandler | ||
{ | ||
protected $authController; | ||
protected $entryController; | ||
protected $duplicationManager; | ||
|
||
public function run() | ||
{ | ||
$this->authController = $this->getService(AuthController::class); | ||
$this->entryController = $this->getService(EntryController::class); | ||
$this->duplicationManager = $this->getService(DuplicationManager::class); | ||
$title = $error = ''; | ||
$toExternalWiki = isset($_GET['toUrl']) && $_GET['toUrl'] == "1"; | ||
if (!$this->wiki->page) { | ||
$error .= $this->render('@templates\alert-message.twig', [ | ||
'type' => 'warning', | ||
'message' => str_replace( | ||
["{beginLink}", "{endLink}"], | ||
["<a href=\"{$this->wiki->href('')}\">", "</a>"], | ||
_t("NOT_FOUND_PAGE") | ||
), | ||
]); | ||
} 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")) { | ||
// si une page PageLogin existe, on l'affiche | ||
$error .= $this->wiki->Format($contenu["body"]); | ||
} else { | ||
// sinon on affiche le formulaire d'identification minimal | ||
$error .= '<div class="vertical-center white-bg">' . "\n" | ||
. '<div class="alert alert-danger alert-error">' . "\n" | ||
. _t('LOGIN_NOT_AUTORIZED') . '. ' . _t('LOGIN_PLEASE_REGISTER') . '.' . "\n" | ||
. '</div>' . "\n" | ||
. $this->wiki->Format('{{login signupurl="0"}}' . "\n\n") | ||
. '</div><!-- end .vertical-center -->' . "\n"; | ||
} | ||
} elseif (!empty($_POST)) { | ||
try { | ||
$data = $this->duplicationManager->checkPostData($_POST); | ||
$this->duplicationManager->duplicateLocally($data); | ||
if ($data['duplicate-action'] == 'edit') { | ||
$this->wiki->Redirect($this->wiki->href('edit', $data['pageTag'])); | ||
return; | ||
seballot marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} else if ($data['duplicate-action'] == 'return') { | ||
$this->wiki->Redirect($this->wiki->href()); | ||
return; | ||
} | ||
$this->wiki->Redirect($this->wiki->href('', $data['pageTag'])); | ||
return; | ||
} catch (\Throwable $th) { | ||
$error .= $this->render('@templates\alert-message-with-back.twig', [ | ||
'type' => 'warning', | ||
'message' => $th->getMessage(), | ||
]); | ||
} | ||
} elseif (!$toExternalWiki && !$this->wiki->UserIsAdmin()) { | ||
$error .= $this->render('@templates\alert-message-with-back.twig', [ | ||
'type' => 'warning', | ||
'message' => _t('ONLY_ADMINS_CAN_DUPLICATE') . '.', | ||
]); | ||
} elseif ($this->getService(AclService::class)->hasAccess('read', $this->wiki->GetPageTag())) { | ||
$isEntry = $this->getService(EntryManager::class)->isEntry($this->wiki->GetPageTag()); | ||
$isList = $this->getService(ListManager::class)->isList($this->wiki->GetPageTag()); | ||
$type = $isEntry ? 'entry' : ($isList ? 'list' : 'page'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pour info, c'est pas trop recommendé d'utiliser des "magic string" comme ça, mieux vaut utiliser des enum ou des constantes There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tu parles de l'opérateur ternaire? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. non, de créer une variable qui a plusieurs valeurs potentielle (entry, list, page) et de la passer de methode en methode, sans savoir quelles sont les valeurs potentielles, par example avec une enum
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Les enums c'est pour php>=8.1, trop récent pour yeswiki |
||
$pageTitle = ''; | ||
if ($isEntry) { | ||
$title = _t('TEMPLATE_DUPLICATE_ENTRY') . ' ' . $this->wiki->GetPageTag(); | ||
$pageContent = $this->getService(EntryManager::class)->getOne($this->wiki->GetPageTag()); | ||
if ($toExternalWiki) { | ||
$pageTitle = $pageContent['bf_titre']; | ||
$proposedTag = $this->wiki->GetPageTag(); | ||
$pageContent = $this->wiki->page['body']; | ||
} else { | ||
$pageTitle = $pageContent['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()); | ||
if ($toExternalWiki) { | ||
$pageTitle = $pageContent['titre_liste']; | ||
$proposedTag = $this->wiki->GetPageTag(); | ||
} else { | ||
$pageTitle = $pageContent['titre_liste'] . ' (' . _t('DUPLICATE') . ')'; | ||
$proposedTag = genere_nom_wiki('Liste ' . $pageTitle); | ||
} | ||
} else { // page | ||
$title = _t('TEMPLATE_DUPLICATE_PAGE') . ' ' . $this->wiki->GetPageTag(); | ||
if ($toExternalWiki) { | ||
$proposedTag = $this->wiki->GetPageTag(); | ||
} else { | ||
$proposedTag = genere_nom_wiki($this->wiki->GetPageTag() . ' ' . _t('DUPLICATE')); | ||
} | ||
$pageContent = $this->wiki->page['body']; | ||
} | ||
$attachments = $this->duplicationManager->findFiles($this->wiki->page['tag']); | ||
$totalSize = 0; | ||
foreach ($attachments as $a) { | ||
$totalSize = $totalSize + $a['size']; | ||
} | ||
} | ||
|
||
if ($toExternalWiki) { | ||
$title .= ' ' . _t('TO_ANOTHER_YESWIKI'); | ||
} | ||
// in ajax request for modal, no title | ||
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { | ||
$title = ''; | ||
} | ||
return $this->renderInSquelette('@core/handlers/duplicate.twig', [ | ||
'title' => $title, | ||
'originalTag' => $this->wiki->GetPageTag(), | ||
'error' => $error, | ||
'sourceUrl' => $this->wiki->href(), | ||
'proposedTag' => $proposedTag ?? '', | ||
'attachments' => $attachments ?? [], | ||
'pageTitle' => $pageTitle ?? '', | ||
'pageContent' => $pageContent ?? '', | ||
'totalSize' => $this->duplicationManager->humanFilesize($totalSize ?? 0), | ||
'type' => $type ?? '', | ||
'baseUrl' => preg_replace('/\?$/Ui', '', $this->wiki->config['base_url']), | ||
'toExternalWiki' => $toExternalWiki, | ||
]); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,11 +3,11 @@ | |
namespace YesWiki\Core\Controller; | ||
|
||
use Exception; | ||
use Throwable; | ||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\Routing\Annotation\Route; | ||
use Symfony\Component\Security\Csrf\Exception\TokenNotFoundException; | ||
use Throwable; | ||
use YesWiki\Bazar\Controller\EntryController; | ||
use YesWiki\Bazar\Service\EntryManager; | ||
use YesWiki\Core\ApiResponse; | ||
|
@@ -16,14 +16,13 @@ | |
use YesWiki\Core\Service\AclService; | ||
use YesWiki\Core\Service\ArchiveService; | ||
use YesWiki\Core\Service\CommentService; | ||
use YesWiki\Core\Service\DbService; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. c'est une erreur d'avoir retiré cet import, c'est utilisé. J'ai fait un fix There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. je croies que j'avais corrigé ca et le missing { mais j'ai pas du bien reprendre mon commit lors du cherry-pick |
||
use YesWiki\Core\Service\DiffService; | ||
use YesWiki\Core\Service\DuplicationManager; | ||
use YesWiki\Core\Service\PageManager; | ||
use YesWiki\Core\Service\ReactionManager; | ||
use YesWiki\Core\Service\TripleStore; | ||
use YesWiki\Core\Service\UserManager; | ||
use YesWiki\Core\YesWikiController; | ||
use YesWiki\Security\Controller\SecurityController; | ||
|
||
class ApiController extends YesWikiController | ||
{ | ||
|
@@ -44,9 +43,15 @@ public function getDocumentation() | |
|
||
$urlPages = $this->wiki->Href('', 'api/pages'); | ||
$output .= '<h2>' . _t('PAGES') . '</h2>' . "\n" . | ||
'<p><code>GET ' . $urlPages . '</code></p>'; | ||
$urlPagesComments = $this->wiki->Href('', 'api/pages/{pageTag}/comments'); | ||
$output .= '<p><code>GET ' . $urlPagesComments . '</code></p>'; | ||
'<p><code>GET ' . $urlPages . '</code><br>Get all pages</p>'; | ||
$urlPages = $this->wiki->Href('', 'api/pages/{pageTag}'); | ||
$output .= '<p><code>GET ' . $urlPages . '</code><br>Get indicated page\'s informations, with raw and html contents</p>'; | ||
|
||
$urlPages = $this->wiki->Href('', 'api/pages/{pageTag}/comments'); | ||
$output .= '<p><code>GET ' . $urlPages . '</code><br>Get indicated page\'s comments</p>'; | ||
|
||
$urlPages = $this->wiki->Href('', 'api/pages/{pageTag}/duplicate'); | ||
$output .= '<p><code>POST ' . $urlPages . '</code><br>Duplicate an external page into this YesWiki pageTag</p>'; | ||
|
||
$urlComments = $this->wiki->Href('', 'api/comments'); | ||
$output .= '<h2>' . _t('COMMENTS') . '</h2>' . "\n" . | ||
|
@@ -65,13 +70,12 @@ public function getDocumentation() | |
'<p><code>POST ' . $urlArchives . '/{id}</code></p>'; | ||
|
||
// TODO use annotations to document the API endpoints | ||
$extensions = $this->wiki->extensions; | ||
foreach ($this->wiki->extensions as $extension => $pluginBase) { | ||
$response = null; | ||
if (file_exists($pluginBase . 'controllers/ApiController.php')) { | ||
$apiClassName = 'YesWiki\\' . ucfirst($extension) . '\\Controller\\ApiController'; | ||
if (!class_exists($apiClassName, false)) { | ||
include $pluginBase . 'controllers/ApiController.php'; | ||
include($pluginBase . 'controllers/ApiController.php'); | ||
} | ||
if (class_exists($apiClassName, false)) { | ||
$apiController = new $apiClassName(); | ||
|
@@ -376,6 +380,21 @@ public function getPage(Request $request, $tag) | |
return new ApiResponse($page); | ||
} | ||
|
||
/** | ||
* @Route("/api/pages/{tag}/duplicate",methods={"POST"},options={"acl":{"public","@admins"}}) | ||
*/ | ||
public function duplicatePage(Request $request, $tag) | ||
{ | ||
$this->denyAccessUnlessAdmin(); | ||
$duplicationManager = $this->getService(DuplicationManager::class); | ||
try { | ||
$duplicationManager->importDistantContent($tag, $request); | ||
} catch (\Throwable $th) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pour info comme y'a un |
||
return new ApiResponse($th->getMessage(), Response::HTTP_FORBIDDEN); | ||
} | ||
return new ApiResponse($request->request->all(), Response::HTTP_OK); | ||
} | ||
|
||
/** | ||
* @Route("/api/pages/{tag}",methods={"DELETE"},options={"acl":{"public","+"}}) | ||
*/ | ||
|
@@ -814,11 +833,14 @@ private function extractTriplesParams(string $method, $resource): array | |
Response::HTTP_BAD_REQUEST | ||
); | ||
} else { | ||
$property = $this->getService(SecurityController::class)->filterInput($method, 'property', FILTER_DEFAULT, true); | ||
$property = filter_input($method, 'property', FILTER_UNSAFE_RAW); | ||
$property = in_array($property, [false, null], true) ? "" : htmlspecialchars(strip_tags($property)); | ||
if (empty($property)) { | ||
$property = null; | ||
} | ||
$username = $this->getService(SecurityController::class)->filterInput($method, 'user', FILTER_DEFAULT, true); | ||
|
||
$username = filter_input($method, 'user', FILTER_UNSAFE_RAW); | ||
$username = in_array($username, [false, null], true) ? "" : htmlspecialchars(strip_tags($username)); | ||
if (empty($username)) { | ||
if (!$this->wiki->UserIsAdmin()) { | ||
$username = $this->getService(AuthController::class)->getLoggedUser()['name']; | ||
|
@@ -834,7 +856,6 @@ private function extractTriplesParams(string $method, $resource): array | |
); | ||
} | ||
} | ||
|
||
return compact(['property', 'username', 'apiResponse']); | ||
} | ||
|
||
|
@@ -853,7 +874,7 @@ public function getArchiveStatus($uid) | |
{ | ||
return $this->getService(ArchiveController::class)->getArchiveStatus( | ||
$uid, | ||
empty($_GET['forceStarted']) ? false : in_array($_GET['forceStarted'], [1, true, '1', 'true'], true) | ||
empty($_GET['forceStarted']) ? false : in_array($_GET['forceStarted'], [1, true, "1", "true"], true) | ||
seballot marked this conversation as resolved.
Show resolved
Hide resolved
|
||
); | ||
} | ||
|
||
|
@@ -910,4 +931,4 @@ public function archivesAction() | |
{ | ||
return $this->getService(ArchiveController::class)->manageArchiveAction(); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
le gars fait la description de sa PR en anglais mais utilise du francais dans le code, gnahaha :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
un peu de french touch dans la codebase!