diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index ab369a6b..125d62a6 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -117,6 +117,11 @@ final class Wall extends VKAPIRequestHandler "type" => "audio", "audio" => $attachment->toVkApiStruct($this->getUser()), ]; + } else if ($attachment instanceof \openvk\Web\Models\Entities\Document) { + $attachments[] = [ + "type" => "doc", + "doc" => $attachment->toVkApiStruct($this->getUser()), + ]; } else if ($attachment instanceof \openvk\Web\Models\Entities\Post) { $repostAttachments = []; @@ -333,6 +338,11 @@ final class Wall extends VKAPIRequestHandler "type" => "audio", "audio" => $attachment->toVkApiStruct($this->getUser()) ]; + } else if ($attachment instanceof \openvk\Web\Models\Entities\Document) { + $attachments[] = [ + "type" => "doc", + "doc" => $attachment->toVkApiStruct($this->getUser()), + ]; } else if ($attachment instanceof \openvk\Web\Models\Entities\Post) { $repostAttachments = []; @@ -577,7 +587,7 @@ final class Wall extends VKAPIRequestHandler if($signed == 1) $flags |= 0b01000000; - $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'poll', 'audio']); + $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'poll', 'audio', 'doc']); $final_attachments = []; $should_be_suggested = $owner_id < 0 && !$wallOwner->canBeModifiedBy($this->getUser()) && $wallOwner->getWallType() == 2; foreach($parsed_attachments as $attachment) { @@ -670,7 +680,7 @@ final class Wall extends VKAPIRequestHandler if(preg_match('/(wall|video|photo)((?:-?)[0-9]+)_([0-9]+)/', $object, $postArray) == 0) $this->fail(100, "One of the parameters specified was missing or invalid: object is incorrect"); - $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio']); + $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio', 'doc']); $final_attachments = []; foreach($parsed_attachments as $attachment) { if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && @@ -780,6 +790,11 @@ final class Wall extends VKAPIRequestHandler "type" => "audio", "audio" => $attachment->toVkApiStruct($this->getUser()), ]; + } else if ($attachment instanceof \openvk\Web\Models\Entities\Document) { + $attachments[] = [ + "type" => "doc", + "doc" => $attachment->toVkApiStruct($this->getUser()), + ]; } } @@ -867,6 +882,11 @@ final class Wall extends VKAPIRequestHandler "type" => "audio", "audio" => $attachment->toVkApiStruct($this->getUser()), ]; + } else if ($attachment instanceof \openvk\Web\Models\Entities\Document) { + $attachments[] = [ + "type" => "doc", + "doc" => $attachment->toVkApiStruct($this->getUser()), + ]; } } @@ -928,7 +948,7 @@ final class Wall extends VKAPIRequestHandler if($post->getTargetWall() < 0) $club = (new ClubsRepo)->get(abs($post->getTargetWall())); - $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio']); + $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio', 'doc']); $final_attachments = []; foreach($parsed_attachments as $attachment) { if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && @@ -1014,7 +1034,7 @@ final class Wall extends VKAPIRequestHandler $this->requireUser(); $this->willExecuteWriteAction(); - $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio', 'poll']); + $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio', 'poll', 'doc']); $final_attachments = []; foreach($parsed_attachments as $attachment) { if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && @@ -1083,7 +1103,7 @@ final class Wall extends VKAPIRequestHandler $this->willExecuteWriteAction(); $comment = (new CommentsRepo)->get($comment_id); - $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio']); + $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio', 'doc']); $final_attachments = []; foreach($parsed_attachments as $attachment) { if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && diff --git a/Web/Models/Entities/Document.php b/Web/Models/Entities/Document.php index 5870548b..4b95ffa2 100644 --- a/Web/Models/Entities/Document.php +++ b/Web/Models/Entities/Document.php @@ -111,7 +111,7 @@ class Document extends Media throw new \ValueError("Invalid filesize"); $hash = hash_file("whirlpool", $file["tmp_name"]); - $this->stateChanges("original_name", $original_name); + $this->stateChanges("original_name", ovk_proc_strtr($original_name, 255)); $this->tmp_format = $file_format; $this->stateChanges("format", $file_format); $this->stateChanges("filesize", $file_size); diff --git a/Web/Models/Entities/User.php b/Web/Models/Entities/User.php index a1f650ec..7e6483cd 100644 --- a/Web/Models/Entities/User.php +++ b/Web/Models/Entities/User.php @@ -512,6 +512,7 @@ class User extends RowModel "links", "poster", "apps", + "docs", ], ])->get($id); } @@ -1117,6 +1118,7 @@ class User extends RowModel "links", "poster", "apps", + "docs", ], ])->set($id, (int) $status)->toInteger(); diff --git a/Web/Models/Repositories/Documents.php b/Web/Models/Repositories/Documents.php index f535418b..2ede28e7 100644 --- a/Web/Models/Repositories/Documents.php +++ b/Web/Models/Repositories/Documents.php @@ -21,7 +21,7 @@ class Documents return is_null($ar) ? NULL : new Document($ar); } - function get(int $id): ?Comment + function get(int $id): ?Document { return $this->toDocument($this->documents->get($id)); } @@ -85,6 +85,14 @@ class Documents ]; } + if(sizeof($response) < 1) { + return [[ + "count" => 0, + "type" => 0, + "name" => tr("document_type_0"), + ]]; + } + return $response; } diff --git a/Web/Presenters/DocumentsPresenter.php b/Web/Presenters/DocumentsPresenter.php index fbf4caf4..9c4bab73 100644 --- a/Web/Presenters/DocumentsPresenter.php +++ b/Web/Presenters/DocumentsPresenter.php @@ -1,6 +1,6 @@ template->_template = "Documents/List.xml"; + if($owner_id > 0) + $this->notFound(); + + if($owner_id < 0) { + $owner = (new Clubs)->get(abs($owner_id)); + if(!$owner || $owner->isBanned()) + $this->notFound(); + else + $this->template->group = $owner; + } + + if(!$owner_id) + $owner_id = $this->user->id; + + $current_tab = (int)($this->queryParam("tab") ?? 0); + $current_order = (int)($this->queryParam("order") ?? 0); + $page = (int)($this->queryParam("p") ?? 1); + $order = in_array($current_order, [0,1,2]) ? $current_order : 0; + $tab = in_array($current_tab, [0,1,2,3,4,5,6,7,8]) ? $current_tab : 0; + + $docs = (new Documents)->getDocumentsByOwner($owner_id, (int)$order, (int)$tab); + $this->template->tabs = (new Documents)->getTypes($owner_id); + $this->template->current_tab = $tab; + $this->template->count = $docs->size(); + $this->template->docs = iterator_to_array($docs->page($page, OPENVK_DEFAULT_PER_PAGE)); + $this->template->locale_string = "you_have_x_documents"; + if($owner_id < 0) { + $this->template->locale_string = "group_has_x_documents"; + } elseif($current_tab != 0) { + $this->template->locale_string = "x_documents_in_tab"; + } + + $this->template->paginatorConf = (object) [ + "count" => $this->template->count, + "page" => $page, + "amount" => sizeof($this->template->docs), + "perPage" => OPENVK_DEFAULT_PER_PAGE, + ]; } function renderListGroup(?int $gid) diff --git a/Web/Presenters/SearchPresenter.php b/Web/Presenters/SearchPresenter.php index 9e16450e..6ab03415 100644 --- a/Web/Presenters/SearchPresenter.php +++ b/Web/Presenters/SearchPresenter.php @@ -1,7 +1,7 @@ videos = new Videos; $this->apps = new Applications; $this->audios = new Audios; + $this->documents = new Documents; parent::__construct(); } @@ -45,7 +47,8 @@ final class SearchPresenter extends OpenVKPresenter "videos" => "videos", "audios" => "audios", "apps" => "apps", - "audios_playlists" => "audios" + "audios_playlists" => "audios", + "docs" => "documents" ]; $parameters = [ "ignore_private" => true, diff --git a/Web/Presenters/UserPresenter.php b/Web/Presenters/UserPresenter.php index dc8fb02c..df3abb82 100644 --- a/Web/Presenters/UserPresenter.php +++ b/Web/Presenters/UserPresenter.php @@ -611,7 +611,8 @@ final class UserPresenter extends OpenVKPresenter "menu_novajoj" => "news", "menu_ligiloj" => "links", "menu_standardo" => "poster", - "menu_aplikoj" => "apps" + "menu_aplikoj" => "apps", + "menu_doxc" => "docs", ]; foreach($settings as $checkbox => $setting) $user->setLeftMenuItemStatus($setting, $this->checkbox($checkbox)); diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml index 245ccfb0..732c527c 100644 --- a/Web/Presenters/templates/@layout.xml +++ b/Web/Presenters/templates/@layout.xml @@ -198,6 +198,11 @@ {_my_apps} {_my_settings} + {if $thisUser->getLeftMenuItemStatus('docs')} + + {_my_documents} + {/if} + {var $canAccessAdminPanel = $thisUser->getChandlerUser()->can("access")->model("admin")->whichBelongsTo(NULL)} {var $canAccessHelpdesk = $thisUser->getChandlerUser()->can("write")->model('openvk\Web\Models\Entities\TicketReply')->whichBelongsTo(0)} {var $menuLinksAvaiable = sizeof(OPENVK_ROOT_CONF['openvk']['preferences']['menu']['links']) > 0 && $thisUser->getLeftMenuItemStatus('links')} @@ -397,6 +402,7 @@ {script "js/scroll.js"} {script "js/player.js"} {script "js/al_wall.js"} + {script "js/al_docs.js"} {script "js/al_api.js"} {script "js/al_mentions.js"} {script "js/al_polls.js"} diff --git a/Web/Presenters/templates/Documents/List.xml b/Web/Presenters/templates/Documents/List.xml index edad9241..c01406e0 100644 --- a/Web/Presenters/templates/Documents/List.xml +++ b/Web/Presenters/templates/Documents/List.xml @@ -1,11 +1,51 @@ {extends "../@layout.xml"} {block title} - + {if !isset($group)} + {_my_documents_objectively} + {else} + {_documents_of_group} + {/if} {/block} -{block header}{/block} +{block header} + {if !isset($group)} + {_my_documents} + {else} + {$group->getCanonicalName()} » + {_my_documents} + {/if} +{/block} {block content} - загрузить +
+ +
+
+ +
+
+
+
+
{tr($locale_string, $count)}.
+
+
+ {if $count > 0} + {foreach $docs as $doc} + {include "components/doc.xml", doc => $doc} + {/foreach} + {else} + {include "../components/error.xml", description => tr("there_is_no_documents_alright")} + {/if} +
+
+
{/block} diff --git a/Web/Presenters/templates/Documents/Upload.xml b/Web/Presenters/templates/Documents/Upload.xml index fcab2fd0..7c91c6b2 100644 --- a/Web/Presenters/templates/Documents/Upload.xml +++ b/Web/Presenters/templates/Documents/Upload.xml @@ -19,18 +19,18 @@ {block content}
- +
- + - + - + - + - + - + - + + + + + +
{_name}:{_name}:
{_tags}:{_tags}:
{_accessbility}:{_accessbility}:
{_file}:{_file}:
diff --git a/Web/Presenters/templates/Documents/components/doc.xml b/Web/Presenters/templates/Documents/components/doc.xml new file mode 100644 index 00000000..baf1b0b8 --- /dev/null +++ b/Web/Presenters/templates/Documents/components/doc.xml @@ -0,0 +1,37 @@ +{var $preview = $doc->hasPreview() ? $doc->getPreview() : NULL} +{var $tags = $doc->getTags()} +{var $copied = $doc->isCopiedBy($thisUser)} +{var $modifiable = $doc->canBeModifiedBy($thisUser)} + +
+ + {if $preview} + document_preview + {else} +
+ {$doc->getFileExtension()} +
+ {/if} +
+
+ {$doc->getName()} + + +
+
+
+
+
+
+
+
diff --git a/Web/Presenters/templates/User/Settings.xml b/Web/Presenters/templates/User/Settings.xml index e7f4b5ac..5ae6ee4b 100644 --- a/Web/Presenters/templates/User/Settings.xml +++ b/Web/Presenters/templates/User/Settings.xml @@ -684,7 +684,19 @@
{_my_apps}
+ + + {_my_documents} +
div { + width: 20px; + height: 20px; + background-color: gray; +} + +.docListViewItem:hover .doc_volume { + display: flex; +} diff --git a/Web/static/js/al_docs.js b/Web/static/js/al_docs.js new file mode 100644 index 00000000..1aca33cf --- /dev/null +++ b/Web/static/js/al_docs.js @@ -0,0 +1 @@ +u() diff --git a/bootstrap.php b/bootstrap.php index e964af81..601129b3 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -261,6 +261,10 @@ function parseAttachments($attachments, array $allow_types = ['photo', 'video', 'method' => 'get', 'onlyId' => true, ], + 'doc' => [ + 'repo' => 'openvk\Web\Models\Repositories\Documents', + 'method' => 'getDocumentById', + ] ]; foreach($exploded_attachments as $attachment_string) { @@ -371,6 +375,18 @@ function escape_html(string $unsafe): string return htmlspecialchars($unsafe, ENT_DISALLOWED | ENT_XHTML); } +function readable_filesize($bytes, $precision = 2): string +{ + $units = ['B', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb']; + + $bytes = max($bytes, 0); + $power = $bytes > 0 ? floor(log($bytes, 1024)) : 0; + $power = min($power, count($units) - 1); + $bytes /= pow(1024, $power); + + return round($bytes, $precision) . $units[$power]; +} + return (function() { _ovk_check_environment(); require __DIR__ . "/vendor/autoload.php"; diff --git a/locales/ru.strings b/locales/ru.strings index f905fe7e..af30d2ec 100644 --- a/locales/ru.strings +++ b/locales/ru.strings @@ -2206,6 +2206,10 @@ /* Documents */ +"my_documents" = "Документы"; +"my_documents_objectively" = "Мои Документы"; +"documents_of_group" = "Документы группы"; +"search_by_documents" = "Поиск по документам..."; "documents" = "Документы"; "document_uploading_in_general" = "Загрузка документа"; "file" = "Файл"; @@ -2221,3 +2225,23 @@ "document_type_6" = "Видео"; "document_type_7" = "Книги"; "document_type_8" = "Остальные"; + +"you_have_x_documents_one" = "У Вас $1 документ"; +"you_have_x_documents_few" = "У Вас $1 документа"; +"you_have_x_documents_many" = "У Вас $1 документов"; +"you_have_x_documents_other" = "У Вас $1 документов"; +"you_have_x_documents_zero" = "У Вас $1 документов"; + +"group_has_x_documents_one" = "У этой группы $1 документ"; +"group_has_x_documents_few" = "У этой группы $1 документа"; +"group_has_x_documents_many" = "У этой группы $1 документов"; +"group_has_x_documents_other" = "У этой группы $1 документов"; +"group_has_x_documents_zero" = "У этой группы $1 документов"; + +"x_documents_in_tab_one" = "В этой вкладке $1 документ"; +"x_documents_in_tab_few" = "В этой вкладке $1 документа"; +"x_documents_in_tab_many" = "В этой вкладке $1 документов"; +"x_documents_in_tab_other" = "В этой вкладке $1 документов"; +"x_documents_in_tab_zero" = "В этой вкладке $1 документов"; + +"there_is_no_documents_alright" = "Здесь нет документов.";