openvk/Web/Models/Entities/Media.php
Alexander Minkin 6ec54a379d
feat: add linting of code (#1220)
* feat(lint): add php-cs-fixer for linting

Removing previous CODE_STYLE as it was not enforced anyway and using PER-CS 2.0.

This is not the reformatting commit.

* style: format code according to PER-CS 2.0 with php-cs-fixer

* ci(actions): add lint action

Resolves #1132.
2025-01-31 18:20:13 +03:00

165 lines
4.7 KiB
PHP

<?php
declare(strict_types=1);
namespace openvk\Web\Models\Entities;
use Nette\InvalidStateException as ISE;
abstract class Media extends Postable
{
protected $fileExtension = "oct"; #octet stream xddd
protected $upperNodeReferenceColumnName = "owner";
protected $processingPlaceholder = null;
protected $processingTime = 30;
public function __destruct()
{
#Remove data, if model wasn't presisted
if (isset($this->changes["hash"])) {
unlink($this->pathFromHash($this->changes["hash"]));
}
}
protected function getBaseDir(): string
{
$uploadSettings = OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"];
if ($uploadSettings["mode"] === "server" && $uploadSettings["server"]["kind"] === "cdn") {
return $uploadSettings["server"]["directory"];
} else {
return OPENVK_ROOT . "/storage/";
}
}
protected function checkIfFileIsProcessed(): bool
{
throw new \LogicException("checkIfFileIsProcessed is not implemented");
}
abstract protected function saveFile(string $filename, string $hash): bool;
protected function pathFromHash(string $hash): string
{
$dir = $this->getBaseDir() . substr($hash, 0, 2);
if (!is_dir($dir)) {
mkdir($dir);
}
return "$dir/$hash." . $this->fileExtension;
}
public function getFileName(): string
{
return $this->pathFromHash($this->getRecord()->hash);
}
public function getURL(): string
{
if (!is_null($this->processingPlaceholder)) {
if (!$this->isProcessed()) {
return "/assets/packages/static/openvk/$this->processingPlaceholder.$this->fileExtension";
}
}
$hash = $this->getRecord()->hash;
switch (OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["mode"]) {
default:
case "default":
case "basic":
return "http://" . $_SERVER['HTTP_HOST'] . "/blob_" . substr($hash, 0, 2) . "/$hash.$this->fileExtension";
break;
case "accelerated":
return "http://" . $_SERVER['HTTP_HOST'] . "/openvk-datastore/$hash.$this->fileExtension";
break;
case "server":
$settings = (object) OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["server"];
return (
$settings->protocol ?? ovk_scheme() .
"://" . $settings->host .
$settings->path .
substr($hash, 0, 2) . "/$hash.$this->fileExtension"
);
break;
}
}
public function getDescription(): ?string
{
return $this->getRecord()->description;
}
protected function isProcessed(): bool
{
if (is_null($this->processingPlaceholder)) {
return true;
}
if ($this->getRecord()->processed) {
return true;
}
$timeDiff = time() - $this->getRecord()->last_checked;
if ($timeDiff < $this->processingTime) {
return false;
}
$res = $this->checkIfFileIsProcessed();
$this->stateChanges("last_checked", time());
$this->stateChanges("processed", $res);
$this->save();
return $res;
}
public function isDeleted(): bool
{
return (bool) $this->getRecord()->deleted;
}
public function setHash(string $hash): void
{
throw new ISE("Setting file hash manually is forbidden");
}
public function setFile(array $file): void
{
if ($file["error"] !== UPLOAD_ERR_OK) {
throw new ISE("File uploaded is corrupted");
}
$hash = hash_file("whirlpool", $file["tmp_name"]);
$this->saveFile($file["tmp_name"], $hash);
$this->stateChanges("hash", $hash);
}
public function save(?bool $log = false): void
{
if (!is_null($this->processingPlaceholder) && is_null($this->getRecord())) {
$this->stateChanges("processed", 0);
$this->stateChanges("last_checked", time());
}
parent::save($log);
}
public function delete(bool $softly = true): void
{
$deleteQuirk = ovkGetQuirk("blobs.erase-upon-deletion");
if ($deleteQuirk === 2 || ($deleteQuirk === 1 && !$softly)) {
@unlink($this->getFileName());
}
parent::delete($softly);
}
public function undelete(): void
{
if (ovkGetQuirk("blobs.erase-upon-deletion") === 2) {
throw new \LogicException("Can't undelete model which is tied to blob, because of config constraint (quriks.yml:blobs.erase-upon-deletion)");
}
parent::undelete();
}
}