diff --git a/Web/Models/Entities/Audio.php b/Web/Models/Entities/Audio.php index 3b998f32..23941f4c 100644 --- a/Web/Models/Entities/Audio.php +++ b/Web/Models/Entities/Audio.php @@ -147,6 +147,11 @@ class Audio extends Media return $this->getRecord()->performer; } + function getPerformers(): array + { + return explode(", ", $this->getRecord()->performer); + } + function getName(): string { return $this->getPerformer() . " — " . $this->getTitle(); diff --git a/Web/Models/Repositories/Audios.php b/Web/Models/Repositories/Audios.php index 73f5ac29..1b8b174d 100644 --- a/Web/Models/Repositories/Audios.php +++ b/Web/Models/Repositories/Audios.php @@ -248,15 +248,17 @@ class Audios { $query = "%$query%"; $result = $this->audios->where([ - "unlisted" => 0, - "deleted" => 0, + "unlisted" => 0, + "deleted" => 0, + /*"withdrawn" => 0, + "processed" => 1,*/ ]); $order_str = (in_array($order['type'], ['id', 'length', 'listens']) ? $order['type'] : 'id') . ' ' . ($order['invert'] ? 'ASC' : 'DESC');; if($params["only_performers"] == "1") { $result->where("performer LIKE ?", $query); } else { - $result->where("name LIKE ? OR performer LIKE ?", $query, $query); + $result->where("CONCAT_WS(' ', performer, name) LIKE ?", $query); } foreach($params as $paramName => $paramValue) { diff --git a/Web/Presenters/AudioPresenter.php b/Web/Presenters/AudioPresenter.php index ae38d1d0..aa8801f5 100644 --- a/Web/Presenters/AudioPresenter.php +++ b/Web/Presenters/AudioPresenter.php @@ -97,9 +97,12 @@ final class AudioPresenter extends OpenVKPresenter $this->template->club = $owner < 0 ? $entity : NULL; $this->template->isMy = ($owner > 0 && ($entity->getId() === $this->user->id)); $this->template->isMyClub = ($owner < 0 && $entity->canBeModifiedBy($this->user->identity)); - } else { - $audios = $this->audios->getPopular(); - $audiosCount = $audios->size(); + } else if ($mode === 'alone_audio') { + $audios = [$this->template->alone_audio]; + $audiosCount = 1; + + $this->template->owner = $this->user->identity; + $this->template->ownerId = $this->user->id; } // $this->renderApp("owner=$owner"); @@ -271,6 +274,19 @@ final class AudioPresenter extends OpenVKPresenter } } + function renderAloneAudio(int $owner_id, int $audio_id): void + { + $this->assertUserLoggedIn(); + + $found_audio = $this->audios->get($audio_id); + if(!$found_audio || $found_audio->isDeleted() || !$found_audio->canBeViewedBy($this->user->identity)) { + $this->notFound(); + } + + $this->template->alone_audio = $found_audio; + $this->renderList(NULL, 'alone_audio'); + } + function renderListen(int $id): void { if ($_SERVER["REQUEST_METHOD"] === "POST") { @@ -327,17 +343,15 @@ final class AudioPresenter extends OpenVKPresenter $this->template->club = $club; } - $this->template->owner = $owner; - if ($_SERVER["REQUEST_METHOD"] === "POST") { $title = $this->postParam("title"); $description = $this->postParam("description"); $is_unlisted = (int)$this->postParam('is_unlisted'); - - $audios = !empty($this->postParam("audios")) ? array_slice(explode(",", $this->postParam("audios")), 0, 1000) : []; + $is_ajax = (int)$this->postParam('ajax') == 1; + $audios = array_slice(explode(",", $this->postParam("audios")), 0, 1000); if(empty($title) || iconv_strlen($title) < 1) - $this->flashFail("err", tr("error"), tr("set_playlist_name")); + $this->flashFail("err", tr("error"), tr("set_playlist_name"), NULL, $is_ajax); $playlist = new Playlist; $playlist->setOwner($owner); @@ -348,12 +362,12 @@ final class AudioPresenter extends OpenVKPresenter if($_FILES["cover"]["error"] === UPLOAD_ERR_OK) { if(!str_starts_with($_FILES["cover"]["type"], "image")) - $this->flashFail("err", tr("error"), tr("not_a_photo")); + $this->flashFail("err", tr("error"), tr("not_a_photo"), NULL, $is_ajax); try { $playlist->fastMakeCover($this->user->id, $_FILES["cover"]); } catch(\Throwable $e) { - $this->flashFail("err", tr("error"), tr("invalid_cover_photo")); + $this->flashFail("err", tr("error"), tr("invalid_cover_photo"), NULL, $is_ajax); } } @@ -361,25 +375,22 @@ final class AudioPresenter extends OpenVKPresenter foreach($audios as $audio) { $audio = $this->audios->get((int)$audio); - - if(!$audio || $audio->isDeleted() || !$audio->canBeViewedBy($this->user->identity)) + if(!$audio || $audio->isDeleted()) continue; $playlist->add($audio); } $playlist->bookmark(isset($club) ? $club : $this->user->identity); + if($is_ajax) { + $this->returnJson([ + 'success' => true, + 'redirect' => '/playlist' . $owner . "_" . $playlist->getId() + ]); + } $this->redirect("/playlist" . $owner . "_" . $playlist->getId()); } else { - if(isset($club)) { - $this->template->audios = iterator_to_array($this->audios->getByClub($club, 1, 10)); - $count = (new Audios)->getClubCollectionSize($club); - } else { - $this->template->audios = iterator_to_array($this->audios->getByUser($this->user->identity, 1, 10)); - $count = (new Audios)->getUserCollectionSize($this->user->identity); - } - - $this->template->pagesCount = ceil($count / 10); + $this->template->owner = $owner; } } @@ -435,28 +446,20 @@ final class AudioPresenter extends OpenVKPresenter $this->willExecuteWriteAction(); $playlist = $this->audios->getPlaylistByOwnerAndVID($owner_id, $virtual_id); - $page = (int)($this->queryParam("p") ?? 1); if (!$playlist || $playlist->isDeleted() || !$playlist->canBeModifiedBy($this->user->identity)) $this->notFound(); $this->template->playlist = $playlist; - $this->template->page = $page; $audios = iterator_to_array($playlist->fetch(1, $playlist->size())); - $this->template->audios = array_slice($audios, 0, 10); - $audiosIds = []; - - foreach($audios as $aud) - $audiosIds[] = $aud->getId(); - - $this->template->audiosIds = implode(",", array_unique($audiosIds)) . ","; + $this->template->audios = array_slice($audios, 0, 1000); $this->template->ownerId = $owner_id; $this->template->owner = $playlist->getOwner(); - $this->template->pagesCount = $pagesCount = ceil($playlist->size() / 10); if($_SERVER["REQUEST_METHOD"] !== "POST") return; + $is_ajax = (int)$this->postParam('ajax') == 1; $title = $this->postParam("title"); $description = $this->postParam("description"); $is_unlisted = (int)$this->postParam('is_unlisted'); @@ -471,12 +474,12 @@ final class AudioPresenter extends OpenVKPresenter $playlist->resetLength(); $playlist->setUnlisted((bool)$is_unlisted); - if($_FILES["new_cover"]["error"] === UPLOAD_ERR_OK) { - if(!str_starts_with($_FILES["new_cover"]["type"], "image")) + if($_FILES["cover"]["error"] === UPLOAD_ERR_OK) { + if(!str_starts_with($_FILES["cover"]["type"], "image")) $this->flashFail("err", tr("error"), tr("not_a_photo")); try { - $playlist->fastMakeCover($this->user->id, $_FILES["new_cover"]); + $playlist->fastMakeCover($this->user->id, $_FILES["cover"]); } catch(\Throwable $e) { $this->flashFail("err", tr("error"), tr("invalid_cover_photo")); } @@ -490,13 +493,18 @@ final class AudioPresenter extends OpenVKPresenter foreach ($new_audios as $new_audio) { $audio = (new Audios)->get((int)$new_audio); - if(!$audio || $audio->isDeleted()) continue; $playlist->add($audio); } + if($is_ajax) { + $this->returnJson([ + 'success' => true, + 'redirect' => '/playlist' . $playlist->getPrettyId() + ]); + } $this->redirect("/playlist".$playlist->getPrettyId()); } @@ -762,6 +770,15 @@ final class AudioPresenter extends OpenVKPresenter $audios = $stream->page($page, 10); $audiosCount = $stream->size(); break; + case 'alone_audio': + $found_audio = $this->audios->get($ctx_id); + if(!$found_audio || $found_audio->isDeleted() || !$found_audio->canBeViewedBy($this->user->identity)) { + $this->flashFail("err", "Error", "Not found", 89, true); + } + + $audios = [$found_audio]; + $audiosCount = 1; + break; } $pagesCount = ceil($audiosCount / $perPage); @@ -779,16 +796,21 @@ final class AudioPresenter extends OpenVKPresenter $audiosArr = []; foreach($audios as $audio) { - $audiosArr[] = [ - "id" => $audio->getId(), - "name" => $audio->getTitle(), - "performer" => $audio->getPerformer(), - "keys" => $audio->getKeys(), - "url" => $audio->getUrl(), - "length" => $audio->getLength(), - "available" => $audio->isAvailable(), - "withdrawn" => $audio->isWithdrawn(), - ]; + $output_array = []; + $output_array['id'] = $audio->getId(); + $output_array['name'] = $audio->getTitle(); + $output_array['performer'] = $audio->getPerformer(); + + if(!$audio->isWithdrawn()) { + $output_array['keys'] = $audio->getKeys(); + $output_array['url'] = $audio->getUrl(); + } + + $output_array['length'] = $audio->getLength(); + $output_array['available'] = $audio->isAvailable(); + $output_array['withdrawn'] = $audio->isWithdrawn(); + + $audiosArr[] = $output_array; } $resultArr = [ diff --git a/Web/Presenters/AuthPresenter.php b/Web/Presenters/AuthPresenter.php index 7edcda7c..6db7758c 100644 --- a/Web/Presenters/AuthPresenter.php +++ b/Web/Presenters/AuthPresenter.php @@ -228,6 +228,7 @@ final class AuthPresenter extends OpenVKPresenter return; } + $this->template->disable_ajax = 1; $this->template->is2faEnabled = $request->getUser()->is2faEnabled(); if($_SERVER["REQUEST_METHOD"] === "POST") { diff --git a/Web/Presenters/MessengerPresenter.php b/Web/Presenters/MessengerPresenter.php index e04e1adc..cec99cff 100644 --- a/Web/Presenters/MessengerPresenter.php +++ b/Web/Presenters/MessengerPresenter.php @@ -63,6 +63,7 @@ final class MessengerPresenter extends OpenVKPresenter $this->flash("err", tr("warning"), tr("user_may_not_reply")); } + $this->template->disable_ajax = 1; $this->template->selId = $sel; $this->template->correspondent = $correspondent; } diff --git a/Web/Presenters/NoSpamPresenter.php b/Web/Presenters/NoSpamPresenter.php index 8164d05e..714cac93 100644 --- a/Web/Presenters/NoSpamPresenter.php +++ b/Web/Presenters/NoSpamPresenter.php @@ -38,6 +38,7 @@ final class NoSpamPresenter extends OpenVKPresenter if ($mode === "form") { $this->template->_template = "NoSpam/Index"; + $this->template->disable_ajax = 1; $foundClasses = []; foreach (Finder::findFiles('*.php')->from($targetDir) as $file) { $content = file_get_contents($file->getPathname()); @@ -67,6 +68,7 @@ final class NoSpamPresenter extends OpenVKPresenter $this->template->models = $models; } else if ($mode === "templates") { $this->template->_template = "NoSpam/Templates.xml"; + $this->template->disable_ajax = 1; $filter = []; if ($this->queryParam("id")) { $filter["id"] = (int)$this->queryParam("id"); diff --git a/Web/Presenters/OpenVKPresenter.php b/Web/Presenters/OpenVKPresenter.php index 6df21bd2..1d03a1c2 100644 --- a/Web/Presenters/OpenVKPresenter.php +++ b/Web/Presenters/OpenVKPresenter.php @@ -282,11 +282,11 @@ abstract class OpenVKPresenter extends SimplePresenter $this->redirect("/maintenances/"); } } - - /*if($this->queryParam('al') == '1') { - $this->assertNoCSRF(); + + if($_SERVER['HTTP_X_OPENVK_AJAX_QUERY'] == '1' && $this->user->identity) { + error_reporting(0); header('Content-Type: text/plain; charset=UTF-8'); - }*/ + } parent::onStartup(); } diff --git a/Web/Presenters/ReportPresenter.php b/Web/Presenters/ReportPresenter.php index 0c4cbd83..a627efa4 100644 --- a/Web/Presenters/ReportPresenter.php +++ b/Web/Presenters/ReportPresenter.php @@ -43,6 +43,7 @@ final class ReportPresenter extends OpenVKPresenter "perPage" => 15, ]; $this->template->mode = $act ?? "all"; + $this->template->disable_ajax = 1; if ($_SERVER["REQUEST_METHOD"] === "POST") { $reports = []; @@ -78,6 +79,7 @@ final class ReportPresenter extends OpenVKPresenter $this->notFound(); $this->template->report = $report; + $this->template->disable_ajax = 1; } function renderCreate(int $id): void diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml index 0e514bb8..b7d84b96 100644 --- a/Web/Presenters/templates/@layout.xml +++ b/Web/Presenters/templates/@layout.xml @@ -20,7 +20,6 @@ {script "js/utils.js"} {script "js/node_modules/dashjs/dist/dash.all.min.js"} - {script "js/al_music.js"} {css "js/node_modules/tippy.js/dist/backdrop.css"} {css "js/node_modules/cropperjs/dist/cropper.css"} @@ -31,6 +30,10 @@ {script "js/node_modules/@popperjs/core/dist/umd/popper.min.js"} {script "js/node_modules/tippy.js/dist/tippy-bundle.umd.min.js"} {script "js/node_modules/handlebars/dist/handlebars.min.js"} + {script "js/node_modules/react/dist/react-with-addons.min.js"} + {script "js/node_modules/react-dom/dist/react-dom.min.js"} + {script "js/vnd_literallycanvas.js"} + {css "js/node_modules/literallycanvas/lib/css/literallycanvas.css"} {if $isTimezoned == NULL} {script "js/timezone.js"} @@ -199,18 +202,18 @@ {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')}
- {_admin} - {_helpdesk} + {_admin} + {_helpdesk} {if $helpdeskTicketNotAnsweredCount > 0} ({$helpdeskTicketNotAnsweredCount}) {/if} - {tr("reports")} + {tr("reports")} {if $reportNotAnsweredCount > 0} ({$reportNotAnsweredCount}) {/if} - + noSpam - {ifset bodyScripts} {include bodyScripts} {/ifset} + {script "js/router.js"}