add editing functions

This commit is contained in:
mrilyew 2024-12-29 15:58:31 +03:00
parent 36560555b6
commit 41b2947ba4
10 changed files with 117 additions and 38 deletions

View file

@ -50,7 +50,7 @@ final class Docs extends VKAPIRequestHandler
return $this->add($owner_id, $doc_id, ""); return $this->add($owner_id, $doc_id, "");
} }
function edit(int $owner_id, int $doc_id, ?string $title, ?string $tags, ?int $folder_id): int function edit(int $owner_id, int $doc_id, ?string $title = "", ?string $tags = "", ?int $folder_id = 0, int $owner_hidden = -1): int
{ {
$this->requireUser(); $this->requireUser();
$this->willExecuteWriteAction(); $this->willExecuteWriteAction();
@ -69,16 +69,16 @@ final class Docs extends VKAPIRequestHandler
$doc->setName($title); $doc->setName($title);
if($tags) if($tags)
$doc->setTags($tags); $doc->setTags($tags);
if($folder_id) { if(in_array($folder_id, [0, 3]))
if(in_array($folder_id, [0, 4]))
$doc->setFolder_id($folder_id); $doc->setFolder_id($folder_id);
} if(in_array($owner_hidden, [0, 1]))
$doc->setOwner_hidden($owner_hidden);
try { try {
$doc->setEdited(time()); $doc->setEdited(time());
$doc->save(); $doc->save();
} catch(\Throwable $e) { } catch(\Throwable $e) {
return 1; return 0;
} }
return 1; return 1;

View file

@ -209,10 +209,10 @@ class Document extends Media
$parsed = explode(",", $tags); $parsed = explode(",", $tags);
$result = ""; $result = "";
foreach($parsed as $tag) { foreach($parsed as $tag) {
$result .= mb_trim($tag) . ($tag != end($parsed) ? "," : ''); $result .= trim($tag) . ($tag != end($parsed) ? "," : '');
} }
$this->stateChanges("tags", $result); $this->stateChanges("tags", ovk_proc_strtr($result, 500));
return true; return true;
} }
@ -329,6 +329,7 @@ class Document extends Media
$res->url = $this->getURL(); $res->url = $this->getURL();
$res->date = $this->getPublicationTime()->timestamp(); $res->date = $this->getPublicationTime()->timestamp();
$res->type = $this->getVKAPIType(); $res->type = $this->getVKAPIType();
$res->is_hidden = (int) $this->isOwnerHidden();
$res->is_licensed = (int) $this->isLicensed(); $res->is_licensed = (int) $this->isLicensed();
$res->is_unsafe = (int) $this->isUnsafe(); $res->is_unsafe = (int) $this->isUnsafe();
$res->folder_id = (int) $this->getFolder(); $res->folder_id = (int) $this->getFolder();
@ -346,16 +347,25 @@ class Document extends Media
return $res; return $res;
} }
function delete(bool $softly = true, bool $all_copies = false): void
{
if($all_copies) {
$ctx = DatabaseConnection::i()->getContext();
$ctx->table("documents")->where("copy_of", $this->getId())->delete();
}
parent::delete($softly);
}
static function detectTypeByFormat(string $format) static function detectTypeByFormat(string $format)
{ {
switch($format) { switch($format) {
case "txt": case "docx": case "doc": case "odt": case "pptx": case "ppt": case "xlsx": case "xls": case "txt": case "docx": case "doc": case "odt": case "pptx": case "ppt": case "xlsx": case "xls": case "md":
return 1; return 1;
case "zip": case "rar": case "7z": case "zip": case "rar": case "7z":
return 2; return 2;
case "gif": case "apng": case "gif": case "apng":
return 3; return 3;
case "jpg": case "jpeg": case "png": case "psd": case "ps": case "jpg": case "jpeg": case "png": case "psd": case "ps": case "webp":
return 4; return 4;
case "mp3": case "mp3":
return 5; return 5;

View file

@ -72,7 +72,7 @@ class Documents
function getTypes(int $owner_id): array function getTypes(int $owner_id): array
{ {
$result = DatabaseConnection::i()->getConnection()->query("SELECT `type`, COUNT(*) AS `count` FROM `documents` WHERE `owner` = $owner_id GROUP BY `type` ORDER BY `type`"); $result = DatabaseConnection::i()->getConnection()->query("SELECT `type`, COUNT(*) AS `count` FROM `documents` WHERE `owner` = $owner_id AND `deleted` = 0 AND `unlisted` = 0 GROUP BY `type` ORDER BY `type`");
$response = []; $response = [];
foreach($result as $res) { foreach($result as $res) {
if($res->count < 1 || $res->type == 0) continue; if($res->count < 1 || $res->type == 0) continue;
@ -113,10 +113,11 @@ class Documents
foreach($params as $paramName => $paramValue) { foreach($params as $paramName => $paramValue) {
switch($paramName) { switch($paramName) {
case "type": case "type":
if($paramValue < 1 || $paramValue > 8) continue;
$result->where("type", $paramValue); $result->where("type", $paramValue);
break; break;
case "tags": case "tags":
$result->where("tags", $paramValue); $result->where("tags LIKE ?", "%$paramValue%");
break; break;
case "from_me": case "from_me":
$result->where("owner", $paramValue); $result->where("owner", $paramValue);

View file

@ -92,9 +92,10 @@ final class DocumentsPresenter extends OpenVKPresenter
$folder = $this->postParam("folder"); $folder = $this->postParam("folder");
$owner_hidden = ($this->postParam("owner_hidden") ?? "off") === "on"; $owner_hidden = ($this->postParam("owner_hidden") ?? "off") === "on";
try {
$document = new Document; $document = new Document;
$document->setOwner($owner); $document->setOwner($owner);
$document->setName($name); $document->setName(ovk_proc_strtr($name, 255));
$document->setFolder_id($folder); $document->setFolder_id($folder);
$document->setTags(empty($tags) ? NULL : $tags); $document->setTags(empty($tags) ? NULL : $tags);
$document->setOwner_hidden($owner_hidden); $document->setOwner_hidden($owner_hidden);
@ -107,6 +108,9 @@ final class DocumentsPresenter extends OpenVKPresenter
]); ]);
$document->save(); $document->save();
} catch(\TypeError $e) {
$this->flashFail("err", tr("forbidden"), $e->getMessage(), null, $isAjax);
}
if(!$isAjax) { if(!$isAjax) {
$this->redirect("/docs" . (isset($group) ? $group->getRealId() : "")); $this->redirect("/docs" . (isset($group) ? $group->getRealId() : ""));

View file

@ -46,14 +46,18 @@
<option n:attr="selected => $order == 2" value="2">{_documents_sort_size}</option> <option n:attr="selected => $order == 2" value="2">{_documents_sort_size}</option>
</select> </select>
</div> </div>
<div class="container_white"> <div class="container_white scroll_container">
{if $count > 0} {if $count > 0}
{foreach $docs as $doc} {foreach $docs as $doc}
<div class="scroll_node">
{include "components/doc.xml", doc => $doc} {include "components/doc.xml", doc => $doc}
</div>
{/foreach} {/foreach}
{else} {else}
{include "../components/error.xml", description => tr("there_is_no_documents_alright")} {include "../components/error.xml", description => tr("there_is_no_documents_alright")}
{/if} {/if}
{include "../components/paginator.xml", conf => $paginatorConf}
</div> </div>
</div> </div>
</div> </div>

View file

@ -14,12 +14,12 @@
{/if} {/if}
</a> </a>
<div class="doc_content noOverflow"> <div class="doc_content noOverflow">
<a><b class="noOverflow">{$doc->getName()}</b></a> <a><b class="noOverflow doc_name">{$doc->getName()}</b></a>
<div class="doc_content_info"> <div class="doc_content_info">
<span>{$doc->getPublicationTime()}</span>, <span>{$doc->getPublicationTime()}</span>,
<span>{readable_filesize($doc->getFilesize())}</span>{if sizeof($tags) > 0} - <span>{readable_filesize($doc->getFilesize())}</span>{if sizeof($tags) > 0} -
<span style="text-wrap: wrap;"> <span class="doc_tags" style="text-wrap: wrap;">
{foreach $tags as $tag} {foreach $tags as $tag}
<a href="/search?section=docs&tags={urlencode($tag)}"> <a href="/search?section=docs&tags={urlencode($tag)}">
{$tag}{if $tag != $tags[sizeof($tags) - 1]},{/if} {$tag}{if $tag != $tags[sizeof($tags) - 1]},{/if}

View file

@ -4015,8 +4015,7 @@ hr {
} }
.docListViewItem { .docListViewItem {
max-height: 52px; min-height: 38px;
height: 38px;
display: grid; display: grid;
grid-template-columns: 0fr 1fr 0fr; grid-template-columns: 0fr 1fr 0fr;
gap: 10px; gap: 10px;
@ -4024,7 +4023,7 @@ hr {
border-bottom: 1px solid #EDEDED; border-bottom: 1px solid #EDEDED;
} }
.docListViewItem:last-of-type { .scroll_node:last-of-type .docListViewItem {
border-bottom: unset !important; border-bottom: unset !important;
} }

View file

@ -45,7 +45,7 @@ function showDocumentUploadDialog(target = null, append_to_url = null)
<input type="text" name="doc_name" value="${name}" placeholder="..."> <input type="text" name="doc_name" value="${name}" placeholder="...">
<label> <label>
<input value="0" type="radio" name="doc_access" checked> <input maxlength="255" value="0" type="radio" name="doc_access" checked>
${tr("private_document")} ${tr("private_document")}
</label> </label>
<br> <br>
@ -55,7 +55,7 @@ function showDocumentUploadDialog(target = null, append_to_url = null)
</label> </label>
<p><b>${tr("tags")}</b></p> <p><b>${tr("tags")}</b></p>
<input type="text" name="doc_tags" placeholder="..."> <input maxlength="256" type="text" name="doc_tags" placeholder="...">
<br> <br>
<label> <label>
<input type="checkbox" name="doc_owner" checked> <input type="checkbox" name="doc_owner" checked>
@ -82,6 +82,8 @@ function showDocumentUploadDialog(target = null, append_to_url = null)
if(json.success) { if(json.success) {
window.router.route(location.href) window.router.route(location.href)
} else {
fastError(escapeHtml(json.flash.message))
} }
}, Function.noop], }, Function.noop],
}) })
@ -90,6 +92,64 @@ function showDocumentUploadDialog(target = null, append_to_url = null)
}) })
} }
u(document).on('click', '.docListViewItem #edit_icon', async (e) => {
const target = u(e.target).closest("#edit_icon")
const item = target.closest('.docListViewItem')
const id = item.nodes[0].dataset.id
CMessageBox.toggleLoader()
const docs = await window.OVKAPI.call('docs.getById', {docs: id, return_tags: 1})
const doc = docs[0]
const cmsg_2 = new CMessageBox({
title: tr("document_editing_in_general"),
body: `
<p><b>${tr("info_name")}</b></p>
<input type="text" name="doc_name" value="${doc.title}" placeholder="...">
<label>
<input maxlength="255" value="0" type="radio" name="doc_access" ${doc.folder_id == 0 ? "checked" : ''}>
${tr("private_document")}
</label>
<br>
<label>
<input value="3" type="radio" name="doc_access" ${doc.folder_id == 3 ? "checked" : ''}>
${tr("public_document")}
</label>
<p><b>${tr("tags")}</b></p>
<input maxlength="256" type="text" name="doc_tags" value="${doc.tags.join(',')}" placeholder="...">
<br>
<label>
<input type="checkbox" name="doc_owner" ${doc.is_hidden ? "checked" : ''}>
${tr("owner_is_hidden")}
</label>
`,
buttons: [tr('save'), tr('cancel')],
callbacks: [async () => {
const params = {
owner_id: id.split('_')[0],
doc_id: id.split('_')[1],
title: u(`input[name='doc_name']`).nodes[0].value,
tags: u(`input[name='doc_tags']`).nodes[0].value,
folder_id: u(`input[name="doc_access"]:checked`).nodes[0].value,
owner_hidden: u(`input[name="doc_owner"]`).nodes[0].checked ? 1 : 0,
}
const edit = await window.OVKAPI.call('docs.edit', params)
if(edit == 1) {
item.find('.doc_content .doc_name').html(escapeHtml(params.title))
item.find('.doc_content .doc_tags').html(escapeHtml(params.tags))
}
}, Function.noop],
})
cmsg_2.getNode().find('.ovk-diag-body').attr('style', "padding:15px;")
cmsg_2.getNode().attr('style', "width: 400px;")
CMessageBox.toggleLoader()
})
u(document).on('click', '#upload_entry_point', (e) => { u(document).on('click', '#upload_entry_point', (e) => {
showDocumentUploadDialog(null, Number(e.target.dataset.gid)) showDocumentUploadDialog(null, Number(e.target.dataset.gid))
}) })
@ -111,7 +171,7 @@ u(document).on('click', '.docListViewItem #remove_icon', async (e) => {
target.removeClass('lagged') target.removeClass('lagged')
if(res == 1) { if(res == 1) {
target.attr('id', 'add_icon') target.attr('id', 'mark_icon')
} }
}) })

View file

@ -2217,6 +2217,7 @@
"search_by_documents" = "Поиск по документам..."; "search_by_documents" = "Поиск по документам...";
"documents" = "Документы"; "documents" = "Документы";
"document_uploading_in_general" = "Загрузка документа"; "document_uploading_in_general" = "Загрузка документа";
"document_editing_in_general" = "Редактирование документа";
"file" = "Файл"; "file" = "Файл";
"tags" = "Теги"; "tags" = "Теги";
"owner_is_hidden" = "Автор скрыт"; "owner_is_hidden" = "Автор скрыт";

View file

@ -24,7 +24,7 @@ openvk:
disableUploading: false disableUploading: false
docs: docs:
maxSize: 10 # in megabytes maxSize: 10 # in megabytes
allowedFormats: ["jpg", "jpeg", "png", "gif", "psd", "aep", "docx", "doc", "odt", "txt", "pptx", "ppt", "xls", "xlsx", "pdf", "djvu", "fb2", "ps", "apk", "zip", "7z", "mp4", "avi", "mp3", "flac"] allowedFormats: ["jpg", "jpeg", "png", "gif", "webp", "psd", "aep", "docx", "doc", "odt", "txt", "md", "pptx", "ppt", "xls", "xlsx", "pdf", "djvu", "fb2", "ps", "apk", "zip", "7z", "mp4", "avi", "mp3", "flac"]
apps: apps:
withdrawTax: 8 withdrawTax: 8
security: security: