openvk/Web/Models/Entities/Postable.php
Jill 6159262026
Add reports (#634)
* Reports: [INDEV] Undone implementation of reports

* Reports: Backend is done

* Reports: Still makin it...

* Reports: Added report window

* Reports: Corrected the content type

* Reports: Make it work

* Reports: Minor fixes and localization

* Reports: Ability to hide Share and Like buttons

Also renamed the .sql file

* Revent some changes from 8f8d7bb

I will move them to the master branch

* Reports: Only for those who can access Helpdesk

* Reports: Modified the route

* Reports: Change the routes

* Reports: Show reports count

* Report: Fix URL

* Обновление репортов (#715)

* Репорты живы

* 2

* Better reports

* Логи

* Update DBEntity.updated.php

* noSpam

* Сбор IP и UserAgent + фикс логирования в IPs

* Новые поля для поиска etc.

* Fixes

* Fixes and enhancements

* Поиск по нескольким разделам

* Reports enhancements

* Совместимость с новыми логами

* Совместимость с новыми логами

* Update Logs.xml

* Update Logs.xml

* Logs i18n

* Update Logs.xml

* Update AdminPresenter.php

---------

Co-authored-by: veselcraft <veselcraft@icloud.com>
Co-authored-by: Ilya Prokopenko <55238545+Xenforce@users.noreply.github.com>
Co-authored-by: n1rwana <aydashkin@vk.com>
2023-08-11 16:50:19 +03:00

179 lines
5.1 KiB
PHP

<?php declare(strict_types=1);
namespace openvk\Web\Models\Entities;
use openvk\Web\Util\DateTime;
use openvk\Web\Models\RowModel;
use openvk\Web\Models\Entities\User;
use openvk\Web\Models\Repositories\Users;
use openvk\Web\Models\Repositories\Clubs;
use openvk\Web\Models\Repositories\Comments;
use Chandler\Database\DatabaseConnection as DB;
use Nette\InvalidStateException as ISE;
use Nette\Database\Table\Selection;
abstract class Postable extends Attachable
{
/**
* Column name, that references to an object, that
* is hieararchically higher than this Postable.
*
* For example: Images belong to User, but Posts belong to Wall.
* Formally users still own posts, but walls also own posts and they are
* their direct parent.
*
* @var string
*/
protected $upperNodeReferenceColumnName = "owner";
private function getTable(): Selection
{
return DB::i()->getContext()->table($this->tableName);
}
function getOwner(bool $real = false): RowModel
{
$oid = (int) $this->getRecord()->owner;
if(!$real && $this->isAnonymous())
$oid = OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["account"];
$oid = abs($oid);
if($oid > 0)
return (new Users)->get($oid);
else
return (new Clubs)->get($oid * -1);
}
function getVirtualId(): int
{
return $this->getRecord()->virtual_id;
}
function getPrettyId(): string
{
return $this->getRecord()->owner . "_" . $this->getVirtualId();
}
function getPublicationTime(): DateTime
{
return new DateTime($this->getRecord()->created);
}
function getEditTime(): ?DateTime
{
$edited = $this->getRecord()->edited;
if(is_null($edited)) return NULL;
return new DateTime($edited);
}
function getComments(int $page, ?int $perPage = NULL): \Traversable
{
return (new Comments)->getCommentsByTarget($this, $page, $perPage);
}
function getCommentsCount(): int
{
return (new Comments)->getCommentsCountByTarget($this);
}
function getLastComments(int $count): \Traversable
{
return (new Comments)->getLastCommentsByTarget($this, $count);
}
function getLikesCount(): int
{
return sizeof(DB::i()->getContext()->table("likes")->where([
"model" => static::class,
"target" => $this->getRecord()->id,
])->group("origin"));
}
# TODO add pagination
function getLikers(): \Traversable
{
$sel = DB::i()->getContext()->table("likes")->where([
"model" => static::class,
"target" => $this->getRecord()->id,
]);
foreach($sel as $like)
yield (new Users)->get($like->origin);
}
function isAnonymous(): bool
{
return (bool) $this->getRecord()->anonymous;
}
function toggleLike(User $user): bool
{
$searchData = [
"origin" => $user->getId(),
"model" => static::class,
"target" => $this->getRecord()->id,
];
if(sizeof(DB::i()->getContext()->table("likes")->where($searchData)) > 0) {
DB::i()->getContext()->table("likes")->where($searchData)->delete();
return false;
}
DB::i()->getContext()->table("likes")->insert($searchData);
return true;
}
function setLike(bool $liked, User $user): void
{
$searchData = [
"origin" => $user->getId(),
"model" => static::class,
"target" => $this->getRecord()->id,
];
if($liked)
DB::i()->getContext()->table("likes")->insert($searchData);
else
DB::i()->getContext()->table("likes")->where($searchData)->delete();
}
function hasLikeFrom(User $user): bool
{
$searchData = [
"origin" => $user->getId(),
"model" => static::class,
"target" => $this->getRecord()->id,
];
return sizeof(DB::i()->getContext()->table("likes")->where($searchData)) > 0;
}
function setVirtual_Id(int $id): void
{
throw new ISE("Setting virtual id manually is forbidden");
}
function save(): void
{
$vref = $this->upperNodeReferenceColumnName;
$vid = $this->getRecord()->{$vref} ?? $this->changes[$vref];
if(!$vid)
throw new ISE("Can't presist post due to inability to calculate it's $vref post count. Have you set it?");
$pCount = sizeof($this->getTable()->where($vref, $vid));
if(is_null($this->getRecord())) {
# lol allow ppl to taint created value
if(!isset($this->changes["created"]))
$this->stateChanges("created", time());
$this->stateChanges("virtual_id", $pCount + 1);
} else {
$this->stateChanges("edited", time());
}
parent::save();
}
use Traits\TAttachmentHost;
use Traits\TOwnable;
}