diff --git a/Web/Models/Entities/MediaCollection.php b/Web/Models/Entities/MediaCollection.php new file mode 100644 index 00000000..05f3835c --- /dev/null +++ b/Web/Models/Entities/MediaCollection.php @@ -0,0 +1,153 @@ +relations = DatabaseConnection::i()->getContext()->table($this->relTableName); + } + + private function entitySuitable(RowModel $entity): bool + { + if(($class = get_class($entity)) !== $this->entityClassName) + throw new \UnexpectedValueException("This MediaCollection can only store '$this->entityClassName' (not '$class')."); + + return true; + } + + function getOwner(): RowModel + { + $oid = $this->getRecord()->owner; + if($oid > 0) + return (new Users)->get($oid); + else + return (new Clubs)->get($oid * -1); + } + + function getPrettyId(): string + { + return $this->getRecord()->owner . "_" . $this->getRecord()->id; + } + + function getName(): string + { + $special = $this->getRecord()->special_type; + if($special === 0) + return $this->getRecord()->name; + + $sName = $this->specialNames[$special]; + if(!$sName) + return $this->getRecord()->name; + + if($sName[0] === "_") + $sName = tr(substr($sName, 1)); + + return $sName; + } + + function getDescription(): ?string + { + return $this->getRecord()->description; + } + + abstract function getCoverURL(): ?string; + + function fetch(int $page = 1, ?int $perPage = NULL): \Traversable + { + $related = $this->getRecord()->related("$this->relTableName.collection")->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE)->order("media ASC"); + foreach($related as $rel) { + $media = $rel->ref($this->entityTableName, "media"); + if(!$media) + continue; + + yield new $this->entityClassName($media); + } + } + + function size(): int + { + return sizeof($this->getRecord()->related("$this->relTableName.collection")); + } + + function getCreationTime(): DateTime + { + return new DateTime($this->getRecord()->created); + } + + function getPublicationTime(): DateTime + { + return $this->getCreationTime(); + } + + function getEditTime(): ?DateTime + { + $edited = $this->getRecord()->edited; + if(is_null($edited)) return NULL; + + return new DateTime($edited); + } + + function isCreatedBySystem(): bool + { + return $this->getRecord()->special_type !== 0; + } + + function add(RowModel $entity): bool + { + $this->entitySuitable($entity); + + if(!$this->allowDuplicates) + if($this->has($entity)) + return false; + + $this->relations->insert([ + "collection" => $this->getId(), + "media" => $entity->getId(), + ]); + + return true; + } + + function remove(RowModel $entity): void + { + $this->entitySuitable($entity); + + $this->relations->where([ + "collection" => $this->getId(), + "media" => $entity->getId(), + ])->delete(); + } + + function has(RowModel $entity): bool + { + $this->entitySuitable($entity); + + $rel = $this->relations->where([ + "collection" => $this->getId(), + "media" => $entity->getId(), + ])->fetch(); + + return !is_null($rel); + } + + use Traits\TOwnable; +} diff --git a/Web/Models/Entities/Photo.php b/Web/Models/Entities/Photo.php index 372be11c..10b941d0 100644 --- a/Web/Models/Entities/Photo.php +++ b/Web/Models/Entities/Photo.php @@ -39,6 +39,6 @@ class Photo extends Media if(is_null($this->getRecord())) throw new ISE("Cannot isolate unpresisted image. Please save() it first."); - DB::i()->getContext()->table("album_relations")->where("photo", $this->getRecord()->id)->delete(); + DB::i()->getContext()->table("album_relations")->where("media", $this->getRecord()->id)->delete(); } } diff --git a/Web/Models/Entities/VideoAlbum.php b/Web/Models/Entities/VideoAlbum.php new file mode 100644 index 00000000..578ecf3d --- /dev/null +++ b/Web/Models/Entities/VideoAlbum.php @@ -0,0 +1,43 @@ + "_added_album", + 32 => "_uploaded_album", + ]; + + function getCoverURL(): ?string + { + $cover = $this->getCoverVideo(); + if(!$cover) + return "/assets/packages/static/openvk/img/camera_200.png"; + + return $cover->getThumbnailURL(); + } + + function getCoverVideo(): ?Photo + { + $cover = $this->getRecord()->cover_video; + if(!$cover) { + $vids = iterator_to_array($this->fetch(1, 1)); + $vid = $vids[0] ?? NULL; + if(!$vid || $vid->isDeleted()) + return NULL; + else + return $vid; + } + + return (new Videos)->get($cover); + } +} diff --git a/bootstrap.php b/bootstrap.php index 5b6e67c7..0f9d47d0 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -137,6 +137,30 @@ function ovk_strftime_safe(string $format, ?int $timestamp = NULL): string return $str; } +function ovk_is_ssl(): bool +{ + if(!isset($GLOBALS["requestIsSSL"])) { + $GLOBALS["requestIsSSL"] = false; + + if(isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] !== "off") { + $GLOBALS["requestIsSSL"] = true; + } else { + $forwardedProto = $_SERVER["HTTP_X_FORWARDED_PROTO"] ?? ($_SERVER["HTTP_X_FORWARDED_PROTOCOL"] ?? ($_SERVER["HTTP_X_URL_SCHEME"] ?? "")); + if($forwardedProto === "https") + $GLOBALS["requestIsSSL"] = true; + else if(($_SERVER["HTTP_X_FORWARDED_SSL"] ?? "") === "on") + $GLOBALS["requestIsSSL"] = true; + } + } + + return $GLOBALS["requestIsSSL"]; +} + +function ovk_scheme(): string +{ + return ovk_is_ssl() ? "https" : "http"; +} + return (function() { _ovk_check_environment(); require __DIR__ . "/vendor/autoload.php"; diff --git a/locales/ru.strings b/locales/ru.strings index 1cd6a9ad..9bb4b2c6 100644 --- a/locales/ru.strings +++ b/locales/ru.strings @@ -206,6 +206,9 @@ "photo" = "Фотография"; "upload_button" = "Загрузить"; +"avatar_album" = "Фотографии со страницы"; +"wall_album" = "Фотографии со стены"; + "albums_zero" = "Ни одного альбома"; "albums_one" = "Один альбом"; "albums_few" = "$1 альбома";