mirror of
https://github.com/openvk/openvk
synced 2025-02-02 04:55:28 +03:00
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.
This commit is contained in:
parent
228f14e384
commit
6ec54a379d
204 changed files with 13964 additions and 10020 deletions
28
.github/workflows/lint.yaml
vendored
Normal file
28
.github/workflows/lint.yaml
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
name: Lint
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
steps:
|
||||||
|
- name: Code Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: "8.2"
|
||||||
|
extensions: gd, zip, intl, yaml, pdo_mysql, rdkafka, imagick
|
||||||
|
tools: composer:v2
|
||||||
|
coverage: none
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: composer install --no-interaction --no-progress --no-suggest --prefer-dist
|
||||||
|
|
||||||
|
- name: PHP CS Fixer
|
||||||
|
run: vendor/bin/php-cs-fixer fix --dry-run --diff
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -15,4 +15,5 @@ themepacks/*
|
||||||
storage/*
|
storage/*
|
||||||
!storage/.gitkeep
|
!storage/.gitkeep
|
||||||
|
|
||||||
.idea
|
.idea
|
||||||
|
.php-cs-fixer.cache
|
||||||
|
|
14
.php-cs-fixer.dist.php
Normal file
14
.php-cs-fixer.dist.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$finder = (new PhpCsFixer\Finder())
|
||||||
|
->in(__DIR__)
|
||||||
|
;
|
||||||
|
|
||||||
|
return (new PhpCsFixer\Config())
|
||||||
|
->setRules([
|
||||||
|
'@PER-CS2.0' => true,
|
||||||
|
'@PHP82Migration' => true,
|
||||||
|
])
|
||||||
|
->setFinder($finder)
|
||||||
|
->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect())
|
||||||
|
;
|
|
@ -1,103 +1,107 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
namespace openvk\CLI;
|
|
||||||
use Chandler\Database\DatabaseConnection;
|
declare(strict_types=1);
|
||||||
use openvk\Web\Models\Repositories\Users;
|
|
||||||
use openvk\Web\Models\Entities\Notifications\CoinsTransferNotification;
|
namespace openvk\CLI;
|
||||||
use Symfony\Component\Console\Command\Command;
|
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Chandler\Database\DatabaseConnection;
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
use openvk\Web\Models\Repositories\Users;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use openvk\Web\Models\Entities\Notifications\CoinsTransferNotification;
|
||||||
use Nette\Utils\ImageException;
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
define("NANOTON", 1000000000);
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
class FetchToncoinTransactions extends Command
|
use Nette\Utils\ImageException;
|
||||||
{
|
|
||||||
private $images;
|
define("NANOTON", 1000000000);
|
||||||
|
|
||||||
protected static $defaultName = "fetch-ton";
|
class FetchToncoinTransactions extends Command
|
||||||
|
{
|
||||||
function __construct()
|
private $images;
|
||||||
{
|
|
||||||
$this->transactions = DatabaseConnection::i()->getContext()->table("cryptotransactions");
|
protected static $defaultName = "fetch-ton";
|
||||||
|
|
||||||
parent::__construct();
|
public function __construct()
|
||||||
}
|
{
|
||||||
|
$this->transactions = DatabaseConnection::i()->getContext()->table("cryptotransactions");
|
||||||
protected function configure(): void
|
|
||||||
{
|
parent::__construct();
|
||||||
$this->setDescription("Fetches TON transactions to top up the users' balance")
|
}
|
||||||
->setHelp("This command checks for new transactions on TON Wallet and then top up the balance of specified users");
|
|
||||||
}
|
protected function configure(): void
|
||||||
|
{
|
||||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
$this->setDescription("Fetches TON transactions to top up the users' balance")
|
||||||
{
|
->setHelp("This command checks for new transactions on TON Wallet and then top up the balance of specified users");
|
||||||
$header = $output->section();
|
}
|
||||||
|
|
||||||
$header->writeln([
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
"TONCOIN Fetcher",
|
{
|
||||||
"=====================",
|
$header = $output->section();
|
||||||
"",
|
|
||||||
]);
|
$header->writeln([
|
||||||
|
"TONCOIN Fetcher",
|
||||||
if(!OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["enabled"]) {
|
"=====================",
|
||||||
$header->writeln("Sorry, but you handn't enabled the TON support in your config file yet.");
|
"",
|
||||||
|
]);
|
||||||
return Command::FAILURE;
|
|
||||||
}
|
if (!OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["enabled"]) {
|
||||||
|
$header->writeln("Sorry, but you handn't enabled the TON support in your config file yet.");
|
||||||
$testnetSubdomain = OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["testnet"] ? "testnet." : "";
|
|
||||||
$url = "https://" . $testnetSubdomain . "toncenter.com/api/v2/getTransactions?";
|
return Command::FAILURE;
|
||||||
|
}
|
||||||
$opts = [
|
|
||||||
"http" => [
|
$testnetSubdomain = OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["testnet"] ? "testnet." : "";
|
||||||
"method" => "GET",
|
$url = "https://" . $testnetSubdomain . "toncenter.com/api/v2/getTransactions?";
|
||||||
"header" => "Accept: application/json"
|
|
||||||
]
|
$opts = [
|
||||||
];
|
"http" => [
|
||||||
|
"method" => "GET",
|
||||||
$selection = $this->transactions->select('hash, lt')->order("id DESC")->limit(1)->fetch();
|
"header" => "Accept: application/json",
|
||||||
$trHash = $selection->hash ?? NULL;
|
],
|
||||||
$trLt = $selection->lt ?? NULL;
|
];
|
||||||
|
|
||||||
$data = http_build_query([
|
$selection = $this->transactions->select('hash, lt')->order("id DESC")->limit(1)->fetch();
|
||||||
"address" => OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["address"],
|
$trHash = $selection->hash ?? null;
|
||||||
"limit" => 100,
|
$trLt = $selection->lt ?? null;
|
||||||
"hash" => $trHash,
|
|
||||||
"to_lt" => $trLt
|
$data = http_build_query([
|
||||||
]);
|
"address" => OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["address"],
|
||||||
|
"limit" => 100,
|
||||||
$response = file_get_contents($url . $data, false, stream_context_create($opts));
|
"hash" => $trHash,
|
||||||
$response = json_decode($response, true);
|
"to_lt" => $trLt,
|
||||||
|
]);
|
||||||
$header->writeln("Gonna up the balance of users");
|
|
||||||
foreach($response["result"] as $transfer) {
|
$response = file_get_contents($url . $data, false, stream_context_create($opts));
|
||||||
$outputArray;
|
$response = json_decode($response, true);
|
||||||
preg_match('/' . OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["regex"] . '/', $transfer["in_msg"]["message"], $outputArray);
|
|
||||||
$userId = ctype_digit($outputArray[1]) ? intval($outputArray[1]) : NULL;
|
$header->writeln("Gonna up the balance of users");
|
||||||
if(is_null($userId)) {
|
foreach ($response["result"] as $transfer) {
|
||||||
$header->writeln("Well, that's a donation. Thanks! XD");
|
$outputArray;
|
||||||
} else {
|
preg_match('/' . OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["regex"] . '/', $transfer["in_msg"]["message"], $outputArray);
|
||||||
$user = (new Users)->get($userId);
|
$userId = ctype_digit($outputArray[1]) ? intval($outputArray[1]) : null;
|
||||||
if(!$user) {
|
if (is_null($userId)) {
|
||||||
$header->writeln("Well, that's a donation. Thanks! XD");
|
$header->writeln("Well, that's a donation. Thanks! XD");
|
||||||
} else {
|
} else {
|
||||||
$value = ($transfer["in_msg"]["value"] / NANOTON) / OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["rate"];
|
$user = (new Users())->get($userId);
|
||||||
$user->setCoins($user->getCoins() + $value);
|
if (!$user) {
|
||||||
$user->save();
|
$header->writeln("Well, that's a donation. Thanks! XD");
|
||||||
(new CoinsTransferNotification($user, (new Users)->get(OPENVK_ROOT_CONF["openvk"]["preferences"]["support"]["adminAccount"]), (int) $value, "Via TON cryptocurrency"))->emit();
|
} else {
|
||||||
$header->writeln($value . " coins are added to " . $user->getId() . " user id");
|
$value = ($transfer["in_msg"]["value"] / NANOTON) / OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["rate"];
|
||||||
$this->transactions->insert([
|
$user->setCoins($user->getCoins() + $value);
|
||||||
"id" => NULL,
|
$user->save();
|
||||||
"hash" => $transfer["transaction_id"]["hash"],
|
(new CoinsTransferNotification($user, (new Users())->get(OPENVK_ROOT_CONF["openvk"]["preferences"]["support"]["adminAccount"]), (int) $value, "Via TON cryptocurrency"))->emit();
|
||||||
"lt" => $transfer["transaction_id"]["lt"]
|
$header->writeln($value . " coins are added to " . $user->getId() . " user id");
|
||||||
]);
|
$this->transactions->insert([
|
||||||
}
|
"id" => null,
|
||||||
}
|
"hash" => $transfer["transaction_id"]["hash"],
|
||||||
}
|
"lt" => $transfer["transaction_id"]["lt"],
|
||||||
|
]);
|
||||||
$header->writeln("Processing finished :3");
|
}
|
||||||
|
}
|
||||||
return Command::SUCCESS;
|
}
|
||||||
}
|
|
||||||
}
|
$header->writeln("Processing finished :3");
|
||||||
|
|
||||||
|
return Command::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\CLI;
|
namespace openvk\CLI;
|
||||||
|
|
||||||
use Chandler\Database\DatabaseConnection;
|
use Chandler\Database\DatabaseConnection;
|
||||||
use openvk\Web\Models\Repositories\Photos;
|
use openvk\Web\Models\Repositories\Photos;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
@ -14,7 +18,7 @@ class RebuildImagesCommand extends Command
|
||||||
|
|
||||||
protected static $defaultName = "build-images";
|
protected static $defaultName = "build-images";
|
||||||
|
|
||||||
function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->images = DatabaseConnection::i()->getContext()->table("photos");
|
$this->images = DatabaseConnection::i()->getContext()->table("photos");
|
||||||
|
|
||||||
|
@ -40,8 +44,9 @@ class RebuildImagesCommand extends Command
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$filter = ["deleted" => false];
|
$filter = ["deleted" => false];
|
||||||
if($input->getOption("upgrade-only"))
|
if ($input->getOption("upgrade-only")) {
|
||||||
$filter["sizes"] = NULL;
|
$filter["sizes"] = null;
|
||||||
|
}
|
||||||
|
|
||||||
$selection = $this->images->select("id")->where($filter);
|
$selection = $this->images->select("id")->where($filter);
|
||||||
$totalPics = $selection->count();
|
$totalPics = $selection->count();
|
||||||
|
@ -52,24 +57,25 @@ class RebuildImagesCommand extends Command
|
||||||
|
|
||||||
$errors = 0;
|
$errors = 0;
|
||||||
$count = 0;
|
$count = 0;
|
||||||
$avgTime = NULL;
|
$avgTime = null;
|
||||||
$begin = new \DateTimeImmutable("now");
|
$begin = new \DateTimeImmutable("now");
|
||||||
foreach($selection as $idHolder) {
|
foreach ($selection as $idHolder) {
|
||||||
$start = microtime(true);
|
$start = microtime(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$photo = (new Photos)->get($idHolder->id);
|
$photo = (new Photos())->get($idHolder->id);
|
||||||
$photo->getSizes(true, true);
|
$photo->getSizes(true, true);
|
||||||
$photo->getDimensions();
|
$photo->getDimensions();
|
||||||
} catch(ImageException $ex) {
|
} catch (ImageException $ex) {
|
||||||
$errors++;
|
$errors++;
|
||||||
}
|
}
|
||||||
|
|
||||||
$timeConsumed = microtime(true) - $start;
|
$timeConsumed = microtime(true) - $start;
|
||||||
if(!$avgTime)
|
if (!$avgTime) {
|
||||||
$avgTime = $timeConsumed;
|
$avgTime = $timeConsumed;
|
||||||
else
|
} else {
|
||||||
$avgTime = ($avgTime + $timeConsumed) / 2;
|
$avgTime = ($avgTime + $timeConsumed) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
$eta = $begin->getTimestamp() + ceil($totalPics * $avgTime);
|
$eta = $begin->getTimestamp() + ceil($totalPics * $avgTime);
|
||||||
$int = (new \DateTimeImmutable("now"))->diff(new \DateTimeImmutable("@$eta"));
|
$int = (new \DateTimeImmutable("now"))->diff(new \DateTimeImmutable("@$eta"));
|
||||||
|
@ -83,4 +89,4 @@ class RebuildImagesCommand extends Command
|
||||||
|
|
||||||
return Command::SUCCESS;
|
return Command::SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
277
CODE_STYLE.md
277
CODE_STYLE.md
|
@ -1,277 +0,0 @@
|
||||||
# Names
|
|
||||||
## Namespace Names
|
|
||||||
Namespaces should be written in PascalCase.
|
|
||||||
|
|
||||||
## File Names
|
|
||||||
Code directories should have their name written in PascalCase. Code files should contain only one class and have the name of that class.
|
|
||||||
In case of multiple class definitions in one file, it's name should be the same as the "primary" class name.
|
|
||||||
Non-code directories, non-class and non-code files should be named in lisp-case.
|
|
||||||
|
|
||||||
## Variable Names
|
|
||||||
Variable names should be written in camelCase. This also applies to function arguments, class instance names and methods.
|
|
||||||
|
|
||||||
## Constant Names
|
|
||||||
Constants are written in SCREAMING_SNAKE_CASE, but should be declared case-insensetive.
|
|
||||||
|
|
||||||
## Class Names
|
|
||||||
Classes in OpenVK should belong to `openvk\` namespace and be in the corresponding directory (according to PSR-4). Names of classes should be written in PascalCase.
|
|
||||||
|
|
||||||
## Function Names
|
|
||||||
camelCase and snake_case are allowed, but first one is the recommended way. This rule does not apply to class methods, which are written in camelCase only.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Coding Rules
|
|
||||||
## File header
|
|
||||||
All OpenVK files must start with `<?php` open-tag followed by `declare(strict_types=1);` on the same line. The next line must contain namespace.
|
|
||||||
The lines after must contain use-declarations, each on it's own line (usage of {} operator is OK), if there is any. Then there must be an empty line. Example:
|
|
||||||
```php
|
|
||||||
<?php declare(strict_types=1);
|
|
||||||
namespace openvk;
|
|
||||||
use Chandler\Database\DatabaseConnection;
|
|
||||||
use Nette\Utils\{Image, FileSystem};
|
|
||||||
|
|
||||||
class ...
|
|
||||||
```
|
|
||||||
|
|
||||||
## NULL
|
|
||||||
Null should be written as constant, all-uppercase: `NULL`.
|
|
||||||
|
|
||||||
## Nullable (optional) pointer arguments
|
|
||||||
Optional pointer arguments should default to `nullptr`: `function something(&int? $myPointer = nullptr)`. `nullptr` must be written in lisp-case (lowercase).
|
|
||||||
|
|
||||||
## Comparing to NULL
|
|
||||||
In OpenVK `is_null` is the preferred way to check for equality to NULL. `??` must be used in assignments and where else possible.
|
|
||||||
In case if value can either be NULL or truthy, "boolean not" should be used to check if value is not null: `if(!$var)`.
|
|
||||||
|
|
||||||
## Arrays
|
|
||||||
Arrays must be defined with modern syntax: `[1, 2, 3]` (NOT `array(1, 2, 3)`).
|
|
||||||
Same applies to `list` construction: use `[$a, , $b] = $arr;` instead of `list($a, , $b) = $arr;`
|
|
||||||
|
|
||||||
## Casts
|
|
||||||
Typecasts must be done with modern syntax where possible: `(type) $var`. Int-to-string, string-to-int, etc conversions should also be dont with modern casting
|
|
||||||
syntax where possible, but should use `ctype_` functions where needed. `gettype`, `settype` should be used in dynamic programming only.
|
|
||||||
|
|
||||||
## Goto
|
|
||||||
```goto``` should be avoided.
|
|
||||||
|
|
||||||
## `continue n; `
|
|
||||||
It is preferable to use `continue n`, `break n` instead of guarding flags:
|
|
||||||
```php
|
|
||||||
# COOL AND GOOD
|
|
||||||
foreach($a as $b)
|
|
||||||
foreach($b as $c)
|
|
||||||
if($b == $c)
|
|
||||||
break 2;
|
|
||||||
|
|
||||||
# BRUH
|
|
||||||
foreach($a as $b) {
|
|
||||||
$shouldBreak = false;
|
|
||||||
foreach($b as $c)
|
|
||||||
if($b == $c)
|
|
||||||
$shouldBreak = true;
|
|
||||||
|
|
||||||
if($shouldBreak)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Comments
|
|
||||||
In OpenVK we use Perl-style `#` for single-line comments.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Formatting
|
|
||||||
## Variables
|
|
||||||
It is preferable to declare only one variable per line in the code.
|
|
||||||
|
|
||||||
## Indentation
|
|
||||||
All things in OpenVK must be properly indented by a sequence of 4 spaces. Not tabs. \
|
|
||||||
When there are several variable declarations listed together, line up the variables:
|
|
||||||
```php
|
|
||||||
# OK
|
|
||||||
$photos = (new Photos)->where("meow", true);
|
|
||||||
$photo = $photos->fetch();
|
|
||||||
$arr = [
|
|
||||||
"a" => 10,
|
|
||||||
"bb" => true,
|
|
||||||
];
|
|
||||||
|
|
||||||
# NOT OK
|
|
||||||
$photos = (new Photos)->where("meow", true);
|
|
||||||
$photo = $photos->fetch();
|
|
||||||
$arr = [
|
|
||||||
"a" => 10,
|
|
||||||
"bb" => true,
|
|
||||||
];
|
|
||||||
```
|
|
||||||
|
|
||||||
## Tab/Space
|
|
||||||
+ **Do not use tabs**. Use spaces, as tabs are defined differently for different editors and printers.
|
|
||||||
+ Put one space after a comma and semicolons: `exp(1, 2)` `for($i = 1; $i < 100; $i++)`
|
|
||||||
+ Put one space around assignment operators: `$a = 1`
|
|
||||||
+ Always put a space around conditional operators: `$a = ($a > $b) ? $a : $b`
|
|
||||||
+ Do not put spaces between unary operators and their operands, primary operators and keywords:
|
|
||||||
```php
|
|
||||||
# OK
|
|
||||||
-$a;
|
|
||||||
$a++;
|
|
||||||
$b[1] = $a;
|
|
||||||
fun($b);
|
|
||||||
if($a) { ... }
|
|
||||||
|
|
||||||
# NOT OK
|
|
||||||
- $a;
|
|
||||||
$a ++;
|
|
||||||
$b [1] = $a;
|
|
||||||
fun ($b);
|
|
||||||
if ($a) { ... }
|
|
||||||
```
|
|
||||||
|
|
||||||
## Blank Lines
|
|
||||||
+ Use blank lines to create paragraphs in the code or comments to make the code more understandable
|
|
||||||
+ Use blank lines before `return` statement if it isn't the only statement in the block
|
|
||||||
+ Use blank lines after shorthand if/else/etc
|
|
||||||
```php
|
|
||||||
# OK
|
|
||||||
if($a)
|
|
||||||
return $x;
|
|
||||||
|
|
||||||
doSomething();
|
|
||||||
|
|
||||||
return "yay";
|
|
||||||
|
|
||||||
# NOT OK
|
|
||||||
if($a) return $x; # return must be on separate line
|
|
||||||
doSomething(); # doSomething must be separated by an extra blank line after short if/else
|
|
||||||
return "yay"; # do use blank lines before return statement
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Method/Function Arguments
|
|
||||||
+ When all arguments for a function do not fit on one line, try to line up the first argument in each line:
|
|
||||||
![image](https://user-images.githubusercontent.com/34442450/167248563-21fb01be-181d-48b9-ac0c-dc953c0a12cf.png)
|
|
||||||
|
|
||||||
+ If the argument lists are still too long to fit on the line, you may line up the arguments with the method name instead.
|
|
||||||
|
|
||||||
## Maximum characters per line
|
|
||||||
Lines should be no more than 80 characters long.
|
|
||||||
|
|
||||||
## Usage of curly braces
|
|
||||||
+ Curly braces should be on separate line for class, method, and function definitions.
|
|
||||||
+ In loops, if/else, try/catch, switch constructions the opening brace should be on the same line as the operator.
|
|
||||||
+ Braces must be ommited if the block contains only one statement **AND** the related blocks are also single statemented.
|
|
||||||
+ Nested single-statement+operator blocks must not be surrounded by braces.
|
|
||||||
```php
|
|
||||||
# OK
|
|
||||||
class A
|
|
||||||
{
|
|
||||||
function doSomethingFunny(): int
|
|
||||||
{
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(true) {
|
|
||||||
doSomething();
|
|
||||||
doSomethingElse();
|
|
||||||
} else {
|
|
||||||
doSomethingFunny();
|
|
||||||
}
|
|
||||||
|
|
||||||
if($a)
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
doSomething();
|
|
||||||
|
|
||||||
foreach($b as $c => $d)
|
|
||||||
if($c == $d)
|
|
||||||
unset($b[$c]);
|
|
||||||
|
|
||||||
# NOT OK
|
|
||||||
class A {
|
|
||||||
function doSomethingFunny(): int {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(true) {
|
|
||||||
doSomething();
|
|
||||||
doSomethingElse();
|
|
||||||
} else
|
|
||||||
doSomethingFunny(); # why?
|
|
||||||
|
|
||||||
if($a) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
doSomething();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($b as $c => $d) {
|
|
||||||
if($c == $d)
|
|
||||||
unset($b[$c]);
|
|
||||||
}
|
|
||||||
|
|
||||||
# lmao
|
|
||||||
if($a) { doSomething(); } else doSomethingElse();
|
|
||||||
```
|
|
||||||
|
|
||||||
## if/else, try/catch
|
|
||||||
+ Operators must not be indented with space from their operands but must have 1-space margin from braces:
|
|
||||||
```php
|
|
||||||
# OK
|
|
||||||
if($a) {
|
|
||||||
doSomething();
|
|
||||||
doSomethingElse();
|
|
||||||
} else if($b) {
|
|
||||||
try {
|
|
||||||
nukeSaintPetersburg('😈');
|
|
||||||
} finally {
|
|
||||||
return PEACE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# NOT OK
|
|
||||||
if ($a) { # do not add space between control flow operator IF and it's operand
|
|
||||||
doSomething();
|
|
||||||
doSomethingElse();
|
|
||||||
}elseif($b){ # do add margin from braces; also ELSE and IF should be separate here
|
|
||||||
try{
|
|
||||||
nukeSaintPetersburg('😈');
|
|
||||||
}finally{
|
|
||||||
return PEACE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Switches
|
|
||||||
+ `break` must be on same indentation level as the code of le case (not the case definiton itself)
|
|
||||||
+ If there is no need to `break` a comment `# NOTICE falling through` must be places instead
|
|
||||||
```php
|
|
||||||
# OK
|
|
||||||
switch($a) {
|
|
||||||
case 1:
|
|
||||||
echo $a;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
echo $a++;
|
|
||||||
# NOTICE falling through
|
|
||||||
|
|
||||||
default:
|
|
||||||
echo "c";
|
|
||||||
}
|
|
||||||
|
|
||||||
# NOT OK
|
|
||||||
switch($a) {
|
|
||||||
case 1:
|
|
||||||
echo $a;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
echo $a++;
|
|
||||||
|
|
||||||
default:
|
|
||||||
echo "c";
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Chandler\Database;
|
namespace Chandler\Database;
|
||||||
|
|
||||||
use Chandler\Database\DatabaseConnection;
|
use Chandler\Database\DatabaseConnection;
|
||||||
use Nette\Database\Table\Selection;
|
use Nette\Database\Table\Selection;
|
||||||
use Nette\Database\Table\ActiveRow;
|
use Nette\Database\Table\ActiveRow;
|
||||||
|
@ -7,9 +11,9 @@ use Nette\InvalidStateException as ISE;
|
||||||
use openvk\Web\Models\Repositories\CurrentUser;
|
use openvk\Web\Models\Repositories\CurrentUser;
|
||||||
use openvk\Web\Models\Repositories\Logs;
|
use openvk\Web\Models\Repositories\Logs;
|
||||||
|
|
||||||
|
|
||||||
abstract class DBEntity
|
abstract class DBEntity
|
||||||
{
|
{
|
||||||
|
use \Nette\SmartObject;
|
||||||
protected $record;
|
protected $record;
|
||||||
protected $changes;
|
protected $changes;
|
||||||
protected $deleted;
|
protected $deleted;
|
||||||
|
@ -17,20 +21,23 @@ abstract class DBEntity
|
||||||
|
|
||||||
protected $tableName;
|
protected $tableName;
|
||||||
|
|
||||||
function __construct(?ActiveRow $row = NULL)
|
public function __construct(?ActiveRow $row = null)
|
||||||
{
|
{
|
||||||
if(is_null($row)) return;
|
if (is_null($row)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$_table = $row->getTable()->getName();
|
$_table = $row->getTable()->getName();
|
||||||
if($_table !== $this->tableName)
|
if ($_table !== $this->tableName) {
|
||||||
throw new ISE("Invalid data supplied for model: table $_table is not compatible with table" . $this->tableName);
|
throw new ISE("Invalid data supplied for model: table $_table is not compatible with table" . $this->tableName);
|
||||||
|
}
|
||||||
|
|
||||||
$this->record = $row;
|
$this->record = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
function __call(string $fName, array $args)
|
public function __call(string $fName, array $args)
|
||||||
{
|
{
|
||||||
if(substr($fName, 0, 3) === "set") {
|
if (substr($fName, 0, 3) === "set") {
|
||||||
$field = mb_strtolower(substr($fName, 3));
|
$field = mb_strtolower(substr($fName, 3));
|
||||||
$this->stateChanges($field, $args[0]);
|
$this->stateChanges($field, $args[0]);
|
||||||
} else {
|
} else {
|
||||||
|
@ -50,38 +57,40 @@ abstract class DBEntity
|
||||||
|
|
||||||
protected function stateChanges(string $column, $value): void
|
protected function stateChanges(string $column, $value): void
|
||||||
{
|
{
|
||||||
if(!is_null($this->record))
|
if (!is_null($this->record)) {
|
||||||
$t = $this->record->{$column}; #Test if column exists
|
$t = $this->record->{$column};
|
||||||
|
} #Test if column exists
|
||||||
|
|
||||||
$this->changes[$column] = $value;
|
$this->changes[$column] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getId()
|
public function getId()
|
||||||
{
|
{
|
||||||
return $this->getRecord()->id;
|
return $this->getRecord()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDeleted(): bool
|
public function isDeleted(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->deleted;
|
return (bool) $this->getRecord()->deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
function unwrap(): object
|
public function unwrap(): object
|
||||||
{
|
{
|
||||||
return (object) $this->getRecord()->toArray();
|
return (object) $this->getRecord()->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete(bool $softly = true): void
|
public function delete(bool $softly = true): void
|
||||||
{
|
{
|
||||||
$user = CurrentUser::i()->getUser();
|
$user = CurrentUser::i()->getUser();
|
||||||
$user_id = is_null($user) ? (int) OPENVK_ROOT_CONF["openvk"]["preferences"]["support"]["adminAccount"] : $user->getId();
|
$user_id = is_null($user) ? (int) OPENVK_ROOT_CONF["openvk"]["preferences"]["support"]["adminAccount"] : $user->getId();
|
||||||
|
|
||||||
if(is_null($this->record))
|
if (is_null($this->record)) {
|
||||||
throw new ISE("Can't delete a model, that hasn't been flushed to DB. Have you forgotten to call save() first?");
|
throw new ISE("Can't delete a model, that hasn't been flushed to DB. Have you forgotten to call save() first?");
|
||||||
|
}
|
||||||
|
|
||||||
(new Logs)->create($user_id, $this->getTable()->getName(), get_class($this), 2, $this->record->toArray(), $this->changes);
|
(new Logs())->create($user_id, $this->getTable()->getName(), get_class($this), 2, $this->record->toArray(), $this->changes);
|
||||||
|
|
||||||
if($softly) {
|
if ($softly) {
|
||||||
$this->record = $this->getTable()->where("id", $this->record->id)->update(["deleted" => true]);
|
$this->record = $this->getTable()->where("id", $this->record->id)->update(["deleted" => true]);
|
||||||
} else {
|
} else {
|
||||||
$this->record->delete();
|
$this->record->delete();
|
||||||
|
@ -89,39 +98,40 @@ abstract class DBEntity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function undelete(): void
|
public function undelete(): void
|
||||||
{
|
{
|
||||||
if(is_null($this->record))
|
if (is_null($this->record)) {
|
||||||
throw new ISE("Can't undelete a model, that hasn't been flushed to DB. Have you forgotten to call save() first?");
|
throw new ISE("Can't undelete a model, that hasn't been flushed to DB. Have you forgotten to call save() first?");
|
||||||
|
}
|
||||||
|
|
||||||
$user = CurrentUser::i()->getUser();
|
$user = CurrentUser::i()->getUser();
|
||||||
$user_id = is_null($user) ? (int) OPENVK_ROOT_CONF["openvk"]["preferences"]["support"]["adminAccount"] : $user->getId();
|
$user_id = is_null($user) ? (int) OPENVK_ROOT_CONF["openvk"]["preferences"]["support"]["adminAccount"] : $user->getId();
|
||||||
|
|
||||||
(new Logs)->create($user_id, $this->getTable()->getName(), get_class($this), 3, $this->record->toArray(), ["deleted" => false]);
|
(new Logs())->create($user_id, $this->getTable()->getName(), get_class($this), 3, $this->record->toArray(), ["deleted" => false]);
|
||||||
|
|
||||||
$this->getTable()->where("id", $this->record->id)->update(["deleted" => false]);
|
$this->getTable()->where("id", $this->record->id)->update(["deleted" => false]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function save(?bool $log = true): void
|
public function save(?bool $log = true): void
|
||||||
{
|
{
|
||||||
if ($log) {
|
if ($log) {
|
||||||
$user = CurrentUser::i();
|
$user = CurrentUser::i();
|
||||||
$user_id = is_null($user) ? (int)OPENVK_ROOT_CONF["openvk"]["preferences"]["support"]["adminAccount"] : $user->getUser()->getId();
|
$user_id = is_null($user) ? (int) OPENVK_ROOT_CONF["openvk"]["preferences"]["support"]["adminAccount"] : $user->getUser()->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_null($this->record)) {
|
if (is_null($this->record)) {
|
||||||
$this->record = $this->getTable()->insert($this->changes);
|
$this->record = $this->getTable()->insert($this->changes);
|
||||||
|
|
||||||
if ($log && $this->getTable()->getName() !== "logs") {
|
if ($log && $this->getTable()->getName() !== "logs") {
|
||||||
(new Logs)->create($user_id, $this->getTable()->getName(), get_class($this), 0, $this->record->toArray(), $this->changes);
|
(new Logs())->create($user_id, $this->getTable()->getName(), get_class($this), 0, $this->record->toArray(), $this->changes);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ($log && $this->getTable()->getName() !== "logs") {
|
if ($log && $this->getTable()->getName() !== "logs") {
|
||||||
(new Logs)->create($user_id, $this->getTable()->getName(), get_class($this), 1, $this->record->toArray(), $this->changes);
|
(new Logs())->create($user_id, $this->getTable()->getName(), get_class($this), 1, $this->record->toArray(), $this->changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->deleted) {
|
if ($this->deleted) {
|
||||||
$this->record = $this->getTable()->insert((array)$this->record);
|
$this->record = $this->getTable()->insert((array) $this->record);
|
||||||
} else {
|
} else {
|
||||||
$this->getTable()->get($this->record->id)->update($this->changes);
|
$this->getTable()->get($this->record->id)->update($this->changes);
|
||||||
$this->record = $this->getTable()->get($this->record->id);
|
$this->record = $this->getTable()->get($this->record->id);
|
||||||
|
@ -131,10 +141,8 @@ abstract class DBEntity
|
||||||
$this->changes = [];
|
$this->changes = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTableName(): string
|
public function getTableName(): string
|
||||||
{
|
{
|
||||||
return $this->getTable()->getName();
|
return $this->getTable()->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
use \Nette\SmartObject;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\ServiceAPI;
|
namespace openvk\ServiceAPI;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\APIToken;
|
use openvk\Web\Models\Entities\APIToken;
|
||||||
|
@ -11,19 +14,19 @@ class Apps implements Handler
|
||||||
{
|
{
|
||||||
private $user;
|
private $user;
|
||||||
private $apps;
|
private $apps;
|
||||||
|
|
||||||
public function __construct(?User $user)
|
public function __construct(?User $user)
|
||||||
{
|
{
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
$this->apps = new Applications;
|
$this->apps = new Applications();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUserInfo(callable $resolve, callable $reject): void
|
public function getUserInfo(callable $resolve, callable $reject): void
|
||||||
{
|
{
|
||||||
$hexId = dechex($this->user->getId());
|
$hexId = dechex($this->user->getId());
|
||||||
$sign = hash_hmac("sha512/224", $hexId, CHANDLER_ROOT_CONF["security"]["secret"], true);
|
$sign = hash_hmac("sha512/224", $hexId, CHANDLER_ROOT_CONF["security"]["secret"], true);
|
||||||
$marketingId = $hexId . "_" . base64_encode($sign);
|
$marketingId = $hexId . "_" . base64_encode($sign);
|
||||||
|
|
||||||
$resolve([
|
$resolve([
|
||||||
"id" => $this->user->getId(),
|
"id" => $this->user->getId(),
|
||||||
"marketing_id" => $marketingId,
|
"marketing_id" => $marketingId,
|
||||||
|
@ -35,82 +38,84 @@ class Apps implements Handler
|
||||||
"ava" => $this->user->getAvatarUrl(),
|
"ava" => $this->user->getAvatarUrl(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePermission(int $app, string $perm, string $state, callable $resolve, callable $reject): void
|
public function updatePermission(int $app, string $perm, string $state, callable $resolve, callable $reject): void
|
||||||
{
|
{
|
||||||
$app = $this->apps->get($app);
|
$app = $this->apps->get($app);
|
||||||
if(!$app || !$app->isEnabled()) {
|
if (!$app || !$app->isEnabled()) {
|
||||||
$reject("No application with this id found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$app->setPermission($this->user, $perm, $state == "yes"))
|
|
||||||
$reject("Invalid permission $perm");
|
|
||||||
|
|
||||||
$resolve(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function pay(int $appId, float $amount, callable $resolve, callable $reject): void
|
|
||||||
{
|
|
||||||
$app = $this->apps->get($appId);
|
|
||||||
if(!$app || !$app->isEnabled()) {
|
|
||||||
$reject("No application with this id found");
|
$reject("No application with this id found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($amount < 0) {
|
if (!$app->setPermission($this->user, $perm, $state == "yes")) {
|
||||||
|
$reject("Invalid permission $perm");
|
||||||
|
}
|
||||||
|
|
||||||
|
$resolve(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function pay(int $appId, float $amount, callable $resolve, callable $reject): void
|
||||||
|
{
|
||||||
|
$app = $this->apps->get($appId);
|
||||||
|
if (!$app || !$app->isEnabled()) {
|
||||||
|
$reject("No application with this id found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($amount < 0) {
|
||||||
$reject(552, "Payment amount is invalid");
|
$reject(552, "Payment amount is invalid");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$coinsLeft = $this->user->getCoins() - $amount;
|
$coinsLeft = $this->user->getCoins() - $amount;
|
||||||
if($coinsLeft < 0) {
|
if ($coinsLeft < 0) {
|
||||||
$reject(41, "Not enough money");
|
$reject(41, "Not enough money");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->user->setCoins($coinsLeft);
|
$this->user->setCoins($coinsLeft);
|
||||||
$this->user->save();
|
$this->user->save();
|
||||||
$app->addCoins($amount);
|
$app->addCoins($amount);
|
||||||
|
|
||||||
$t = time();
|
$t = time();
|
||||||
$resolve($t . "," . hash_hmac("whirlpool", "$appId:$amount:$t", CHANDLER_ROOT_CONF["security"]["secret"]));
|
$resolve($t . "," . hash_hmac("whirlpool", "$appId:$amount:$t", CHANDLER_ROOT_CONF["security"]["secret"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
function withdrawFunds(int $appId, callable $resolve, callable $reject): void
|
public function withdrawFunds(int $appId, callable $resolve, callable $reject): void
|
||||||
{
|
{
|
||||||
$app = $this->apps->get($appId);
|
$app = $this->apps->get($appId);
|
||||||
if(!$app) {
|
if (!$app) {
|
||||||
$reject("No application with this id found");
|
$reject("No application with this id found");
|
||||||
return;
|
return;
|
||||||
} else if($app->getOwner()->getId() != $this->user->getId()) {
|
} elseif ($app->getOwner()->getId() != $this->user->getId()) {
|
||||||
$reject("You don't have rights to edit this app");
|
$reject("You don't have rights to edit this app");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$coins = $app->getBalance();
|
$coins = $app->getBalance();
|
||||||
$app->withdrawCoins();
|
$app->withdrawCoins();
|
||||||
$resolve($coins);
|
$resolve($coins);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRegularToken(string $clientName, bool $acceptsStale, callable $resolve, callable $reject): void
|
public function getRegularToken(string $clientName, bool $acceptsStale, callable $resolve, callable $reject): void
|
||||||
{
|
{
|
||||||
$token = NULL;
|
$token = null;
|
||||||
$stale = true;
|
$stale = true;
|
||||||
if($acceptsStale)
|
if ($acceptsStale) {
|
||||||
$token = (new APITokens)->getStaleByUser($this->user->getId(), $clientName);
|
$token = (new APITokens())->getStaleByUser($this->user->getId(), $clientName);
|
||||||
|
}
|
||||||
if(is_null($token)) {
|
|
||||||
|
if (is_null($token)) {
|
||||||
$stale = false;
|
$stale = false;
|
||||||
$token = new APIToken;
|
$token = new APIToken();
|
||||||
$token->setUser($this->user);
|
$token->setUser($this->user);
|
||||||
$token->setPlatform($clientName ?? (new WhichBrowser\Parser(getallheaders()))->toString());
|
$token->setPlatform($clientName ?? (new WhichBrowser\Parser(getallheaders()))->toString());
|
||||||
$token->save();
|
$token->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
$resolve([
|
$resolve([
|
||||||
'is_stale' => $stale,
|
'is_stale' => $stale,
|
||||||
'token' => $token->getFormattedToken(),
|
'token' => $token->getFormattedToken(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\ServiceAPI;
|
namespace openvk\ServiceAPI;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
use openvk\Web\Models\Repositories\Clubs;
|
use openvk\Web\Models\Repositories\Clubs;
|
||||||
|
|
||||||
|
@ -7,30 +11,30 @@ class Groups implements Handler
|
||||||
{
|
{
|
||||||
protected $user;
|
protected $user;
|
||||||
protected $groups;
|
protected $groups;
|
||||||
|
|
||||||
function __construct(?User $user)
|
public function __construct(?User $user)
|
||||||
{
|
{
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
$this->groups = new Clubs;
|
$this->groups = new Clubs();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getWriteableClubs(callable $resolve, callable $reject)
|
public function getWriteableClubs(callable $resolve, callable $reject)
|
||||||
{
|
{
|
||||||
$clubs = [];
|
$clubs = [];
|
||||||
$wclubs = $this->groups->getWriteableClubs($this->user->getId());
|
$wclubs = $this->groups->getWriteableClubs($this->user->getId());
|
||||||
$count = $this->groups->getWriteableClubsCount($this->user->getId());
|
$count = $this->groups->getWriteableClubsCount($this->user->getId());
|
||||||
|
|
||||||
if(!$count) {
|
if (!$count) {
|
||||||
$reject("You don't have any groups with write access");
|
$reject("You don't have any groups with write access");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($wclubs as $club) {
|
foreach ($wclubs as $club) {
|
||||||
$clubs[] = [
|
$clubs[] = [
|
||||||
"name" => $club->getName(),
|
"name" => $club->getName(),
|
||||||
"id" => $club->getId(),
|
"id" => $club->getId(),
|
||||||
"avatar" => $club->getAvatarUrl() # если в овк когда-нибудь появится крутой список с аватарками, то можно использовать это поле
|
"avatar" => $club->getAvatarUrl(), # если в овк когда-нибудь появится крутой список с аватарками, то можно использовать это поле
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\ServiceAPI;
|
namespace openvk\ServiceAPI;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
|
|
||||||
interface Handler
|
interface Handler
|
||||||
{
|
{
|
||||||
function __construct(?User $user);
|
public function __construct(?User $user);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\ServiceAPI;
|
namespace openvk\ServiceAPI;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
use openvk\Web\Models\Repositories\{Users, Clubs};
|
use openvk\Web\Models\Repositories\{Users, Clubs};
|
||||||
|
|
||||||
|
@ -7,16 +11,16 @@ class Mentions implements Handler
|
||||||
{
|
{
|
||||||
protected $user;
|
protected $user;
|
||||||
|
|
||||||
function __construct(?User $user)
|
public function __construct(?User $user)
|
||||||
{
|
{
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolve(int $id, callable $resolve, callable $reject): void
|
public function resolve(int $id, callable $resolve, callable $reject): void
|
||||||
{
|
{
|
||||||
if($id > 0) {
|
if ($id > 0) {
|
||||||
$user = (new Users)->get($id);
|
$user = (new Users())->get($id);
|
||||||
if(!$user) {
|
if (!$user) {
|
||||||
$reject("Not found");
|
$reject("Not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -32,8 +36,8 @@ class Mentions implements Handler
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$club = (new Clubs)->get(abs($id));
|
$club = (new Clubs())->get(abs($id));
|
||||||
if(!$club) {
|
if (!$club) {
|
||||||
$reject("Not found");
|
$reject("Not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace openvk\ServiceAPI;
|
namespace openvk\ServiceAPI;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
use openvk\Web\Models\Repositories\Notes as NoteRepo;
|
use openvk\Web\Models\Repositories\Notes as NoteRepo;
|
||||||
|
|
||||||
|
@ -8,27 +9,30 @@ class Notes implements Handler
|
||||||
{
|
{
|
||||||
protected $user;
|
protected $user;
|
||||||
protected $notes;
|
protected $notes;
|
||||||
|
|
||||||
function __construct(?User $user)
|
public function __construct(?User $user)
|
||||||
{
|
{
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
$this->notes = new NoteRepo;
|
$this->notes = new NoteRepo();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNote(int $noteId, callable $resolve, callable $reject): void
|
public function getNote(int $noteId, callable $resolve, callable $reject): void
|
||||||
{
|
{
|
||||||
$note = $this->notes->get($noteId);
|
$note = $this->notes->get($noteId);
|
||||||
if(!$note || $note->isDeleted())
|
if (!$note || $note->isDeleted()) {
|
||||||
$reject(83, "Note is gone");
|
$reject(83, "Note is gone");
|
||||||
|
}
|
||||||
|
|
||||||
$noteOwner = $note->getOwner();
|
$noteOwner = $note->getOwner();
|
||||||
assert($noteOwner instanceof User);
|
assert($noteOwner instanceof User);
|
||||||
if(!$noteOwner->getPrivacyPermission("notes.read", $this->user))
|
if (!$noteOwner->getPrivacyPermission("notes.read", $this->user)) {
|
||||||
$reject(160, "You don't have permission to access this note");
|
$reject(160, "You don't have permission to access this note");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$note->canBeViewedBy($this->user))
|
if (!$note->canBeViewedBy($this->user)) {
|
||||||
$reject(15, "Access to note denied");
|
$reject(15, "Access to note denied");
|
||||||
|
}
|
||||||
|
|
||||||
$resolve([
|
$resolve([
|
||||||
"title" => $note->getName(),
|
"title" => $note->getName(),
|
||||||
"link" => "/note" . $note->getPrettyId(),
|
"link" => "/note" . $note->getPrettyId(),
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\ServiceAPI;
|
namespace openvk\ServiceAPI;
|
||||||
|
|
||||||
use Latte\Engine as TemplatingEngine;
|
use Latte\Engine as TemplatingEngine;
|
||||||
use RdKafka\{Conf as RDKConf, KafkaConsumer};
|
use RdKafka\{Conf as RDKConf, KafkaConsumer};
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
|
@ -9,55 +13,55 @@ class Notifications implements Handler
|
||||||
{
|
{
|
||||||
protected $user;
|
protected $user;
|
||||||
protected $notifs;
|
protected $notifs;
|
||||||
|
|
||||||
function __construct(?User $user)
|
public function __construct(?User $user)
|
||||||
{
|
{
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
$this->notifs = new N;
|
$this->notifs = new N();
|
||||||
}
|
}
|
||||||
|
|
||||||
function ack(callable $resolve, callable $reject): void
|
public function ack(callable $resolve, callable $reject): void
|
||||||
{
|
{
|
||||||
$this->user->updateNotificationOffset();
|
$this->user->updateNotificationOffset();
|
||||||
$this->user->save();
|
$this->user->save();
|
||||||
$resolve("OK");
|
$resolve("OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetch(callable $resolve, callable $reject): void
|
public function fetch(callable $resolve, callable $reject): void
|
||||||
{
|
{
|
||||||
$kafkaConf = OPENVK_ROOT_CONF["openvk"]["credentials"]["notificationsBroker"];
|
$kafkaConf = OPENVK_ROOT_CONF["openvk"]["credentials"]["notificationsBroker"];
|
||||||
if(!$kafkaConf["enable"]) {
|
if (!$kafkaConf["enable"]) {
|
||||||
$reject(1999, "Disabled");
|
$reject(1999, "Disabled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$kafkaConf = $kafkaConf["kafka"];
|
$kafkaConf = $kafkaConf["kafka"];
|
||||||
$conf = new RDKConf();
|
$conf = new RDKConf();
|
||||||
$conf->set("metadata.broker.list", $kafkaConf["addr"] . ":" . $kafkaConf["port"]);
|
$conf->set("metadata.broker.list", $kafkaConf["addr"] . ":" . $kafkaConf["port"]);
|
||||||
$conf->set("group.id", "UserFetch-" . $this->user->getId()); # Чтобы уведы приходили только на разные устройства одного чебупелика
|
$conf->set("group.id", "UserFetch-" . $this->user->getId()); # Чтобы уведы приходили только на разные устройства одного чебупелика
|
||||||
$conf->set("auto.offset.reset", "latest");
|
$conf->set("auto.offset.reset", "latest");
|
||||||
|
|
||||||
set_time_limit(30);
|
set_time_limit(30);
|
||||||
$consumer = new KafkaConsumer($conf);
|
$consumer = new KafkaConsumer($conf);
|
||||||
$consumer->subscribe([ $kafkaConf["topic"] ]);
|
$consumer->subscribe([ $kafkaConf["topic"] ]);
|
||||||
|
|
||||||
while(true) {
|
while (true) {
|
||||||
$message = $consumer->consume(30*1000);
|
$message = $consumer->consume(30 * 1000);
|
||||||
switch ($message->err) {
|
switch ($message->err) {
|
||||||
case RD_KAFKA_RESP_ERR_NO_ERROR:
|
case RD_KAFKA_RESP_ERR_NO_ERROR:
|
||||||
$descriptor = $message->payload;
|
$descriptor = $message->payload;
|
||||||
[,$user,] = explode(",", $descriptor);
|
[,$user,] = explode(",", $descriptor);
|
||||||
if(((int) $user) === $this->user->getId()) {
|
if (((int) $user) === $this->user->getId()) {
|
||||||
$data = (object) [];
|
$data = (object) [];
|
||||||
$notification = $this->notifs->fromDescriptor($descriptor, $data);
|
$notification = $this->notifs->fromDescriptor($descriptor, $data);
|
||||||
if(!$notification) {
|
if (!$notification) {
|
||||||
$reject(1982, "Server Error");
|
$reject(1982, "Server Error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$tplDir = __DIR__ . "/../Web/Presenters/templates/components/notifications/";
|
$tplDir = __DIR__ . "/../Web/Presenters/templates/components/notifications/";
|
||||||
$tplId = "$tplDir$data->actionCode/_$data->originModelType" . "_" . $data->targetModelType . "_.xml";
|
$tplId = "$tplDir$data->actionCode/_$data->originModelType" . "_" . $data->targetModelType . "_.xml";
|
||||||
$latte = new TemplatingEngine;
|
$latte = new TemplatingEngine();
|
||||||
$latte->setTempDirectory(CHANDLER_ROOT . "/tmp/cache/templates");
|
$latte->setTempDirectory(CHANDLER_ROOT . "/tmp/cache/templates");
|
||||||
$latte->addFilter("translate", fn($trId) => tr($trId));
|
$latte->addFilter("translate", fn($trId) => tr($trId));
|
||||||
$resolve([
|
$resolve([
|
||||||
|
@ -68,7 +72,7 @@ class Notifications implements Handler
|
||||||
]);
|
]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case RD_KAFKA_RESP_ERR__TIMED_OUT:
|
case RD_KAFKA_RESP_ERR__TIMED_OUT:
|
||||||
case RD_KAFKA_RESP_ERR__PARTITION_EOF:
|
case RD_KAFKA_RESP_ERR__PARTITION_EOF:
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\ServiceAPI;
|
namespace openvk\ServiceAPI;
|
||||||
|
|
||||||
use Chandler\MVC\Routing\Router;
|
use Chandler\MVC\Routing\Router;
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
use openvk\Web\Models\Exceptions\{AlreadyVotedException, InvalidOptionException, PollLockedException};
|
use openvk\Web\Models\Exceptions\{AlreadyVotedException, InvalidOptionException, PollLockedException};
|
||||||
|
@ -10,61 +14,61 @@ class Polls implements Handler
|
||||||
{
|
{
|
||||||
protected $user;
|
protected $user;
|
||||||
protected $polls;
|
protected $polls;
|
||||||
|
|
||||||
function __construct(?User $user)
|
public function __construct(?User $user)
|
||||||
{
|
{
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
$this->polls = new PollRepo;
|
$this->polls = new PollRepo();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getPollHtml(int $poll): string
|
private function getPollHtml(int $poll): string
|
||||||
{
|
{
|
||||||
return Router::i()->execute("/poll$poll", "SAPI");
|
return Router::i()->execute("/poll$poll", "SAPI");
|
||||||
}
|
}
|
||||||
|
|
||||||
function vote(int $pollId, string $options, callable $resolve, callable $reject): void
|
public function vote(int $pollId, string $options, callable $resolve, callable $reject): void
|
||||||
{
|
{
|
||||||
$poll = $this->polls->get($pollId);
|
$poll = $this->polls->get($pollId);
|
||||||
if(!$poll) {
|
if (!$poll) {
|
||||||
$reject("Poll not found");
|
$reject("Poll not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$options = explode(",", $options);
|
$options = explode(",", $options);
|
||||||
$poll->vote($this->user, $options);
|
$poll->vote($this->user, $options);
|
||||||
} catch(AlreadyVotedException $ex) {
|
} catch (AlreadyVotedException $ex) {
|
||||||
$reject("Poll state changed: user has already voted.");
|
$reject("Poll state changed: user has already voted.");
|
||||||
return;
|
return;
|
||||||
} catch(PollLockedException $ex) {
|
} catch (PollLockedException $ex) {
|
||||||
$reject("Poll state changed: poll has ended.");
|
$reject("Poll state changed: poll has ended.");
|
||||||
return;
|
return;
|
||||||
} catch(InvalidOptionException $ex) {
|
} catch (InvalidOptionException $ex) {
|
||||||
$reject("Foreign options passed.");
|
$reject("Foreign options passed.");
|
||||||
return;
|
return;
|
||||||
} catch(UnexpectedValueException $ex) {
|
} catch (UnexpectedValueException $ex) {
|
||||||
$reject("Too much options passed.");
|
$reject("Too much options passed.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$resolve(["html" => $this->getPollHtml($pollId)]);
|
$resolve(["html" => $this->getPollHtml($pollId)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function unvote(int $pollId, callable $resolve, callable $reject): void
|
public function unvote(int $pollId, callable $resolve, callable $reject): void
|
||||||
{
|
{
|
||||||
$poll = $this->polls->get($pollId);
|
$poll = $this->polls->get($pollId);
|
||||||
if(!$poll) {
|
if (!$poll) {
|
||||||
$reject("Poll not found");
|
$reject("Poll not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$poll->revokeVote($this->user);
|
$poll->revokeVote($this->user);
|
||||||
} catch(PollLockedException $ex) {
|
} catch (PollLockedException $ex) {
|
||||||
$reject("Votes can't be revoked from this poll.");
|
$reject("Votes can't be revoked from this poll.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$resolve(["html" => $this->getPollHtml($pollId)]);
|
$resolve(["html" => $this->getPollHtml($pollId)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,27 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\ServiceAPI;
|
namespace openvk\ServiceAPI;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
|
|
||||||
class Service implements Handler
|
class Service implements Handler
|
||||||
{
|
{
|
||||||
protected $user;
|
protected $user;
|
||||||
|
|
||||||
function __construct(?User $user)
|
public function __construct(?User $user)
|
||||||
{
|
{
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTime(callable $resolve, callable $reject): void
|
public function getTime(callable $resolve, callable $reject): void
|
||||||
{
|
{
|
||||||
$resolve(trim((new DateTime)->format("%e %B %G" . tr("time_at_sp") . "%X")));
|
$resolve(trim((new DateTime())->format("%e %B %G" . tr("time_at_sp") . "%X")));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getServerVersion(callable $resolve, callable $reject): void
|
public function getServerVersion(callable $resolve, callable $reject): void
|
||||||
{
|
{
|
||||||
$resolve("OVK " . OPENVK_VERSION);
|
$resolve("OVK " . OPENVK_VERSION);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\ServiceAPI;
|
namespace openvk\ServiceAPI;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\Post;
|
use openvk\Web\Models\Entities\Post;
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
use openvk\Web\Models\Repositories\{Posts, Notes, Videos};
|
use openvk\Web\Models\Repositories\{Posts, Notes, Videos};
|
||||||
|
@ -9,26 +13,29 @@ class Wall implements Handler
|
||||||
protected $user;
|
protected $user;
|
||||||
protected $posts;
|
protected $posts;
|
||||||
protected $notes;
|
protected $notes;
|
||||||
|
|
||||||
function __construct(?User $user)
|
public function __construct(?User $user)
|
||||||
{
|
{
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
$this->posts = new Posts;
|
$this->posts = new Posts();
|
||||||
$this->notes = new Notes;
|
$this->notes = new Notes();
|
||||||
$this->videos = new Videos;
|
$this->videos = new Videos();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPost(int $id, callable $resolve, callable $reject): void
|
public function getPost(int $id, callable $resolve, callable $reject): void
|
||||||
{
|
{
|
||||||
$post = $this->posts->get($id);
|
$post = $this->posts->get($id);
|
||||||
if(!$post || $post->isDeleted())
|
if (!$post || $post->isDeleted()) {
|
||||||
$reject(53, "No post with id=$id");
|
$reject(53, "No post with id=$id");
|
||||||
|
}
|
||||||
|
|
||||||
if($post->getSuggestionType() != 0)
|
if ($post->getSuggestionType() != 0) {
|
||||||
$reject(25, "Can't get suggested post");
|
$reject(25, "Can't get suggested post");
|
||||||
|
}
|
||||||
if(!$post->canBeViewedBy($this->user))
|
|
||||||
|
if (!$post->canBeViewedBy($this->user)) {
|
||||||
$reject(12, "Access denied");
|
$reject(12, "Access denied");
|
||||||
|
}
|
||||||
|
|
||||||
$res = (object) [];
|
$res = (object) [];
|
||||||
$res->id = $post->getId();
|
$res->id = $post->getId();
|
||||||
|
@ -36,21 +43,22 @@ class Wall implements Handler
|
||||||
$res->author = (($owner = $post->getOwner())) instanceof User
|
$res->author = (($owner = $post->getOwner())) instanceof User
|
||||||
? ($owner->getId())
|
? ($owner->getId())
|
||||||
: ($owner->getId() * -1);
|
: ($owner->getId() * -1);
|
||||||
|
|
||||||
if($post->isSigned())
|
if ($post->isSigned()) {
|
||||||
$res->signedOffBy = $post->getOwnerPost();
|
$res->signedOffBy = $post->getOwnerPost();
|
||||||
|
}
|
||||||
|
|
||||||
$res->pinned = $post->isPinned();
|
$res->pinned = $post->isPinned();
|
||||||
$res->sponsored = $post->isAd();
|
$res->sponsored = $post->isAd();
|
||||||
$res->nsfw = $post->isExplicit();
|
$res->nsfw = $post->isExplicit();
|
||||||
$res->text = $post->getText();
|
$res->text = $post->getText();
|
||||||
|
|
||||||
$res->likes = [
|
$res->likes = [
|
||||||
"count" => $post->getLikesCount(),
|
"count" => $post->getLikesCount(),
|
||||||
"hasLike" => $post->hasLikeFrom($this->user),
|
"hasLike" => $post->hasLikeFrom($this->user),
|
||||||
"likedBy" => [],
|
"likedBy" => [],
|
||||||
];
|
];
|
||||||
foreach($post->getLikers() as $liker) {
|
foreach ($post->getLikers() as $liker) {
|
||||||
$res->likes["likedBy"][] = [
|
$res->likes["likedBy"][] = [
|
||||||
"id" => $liker->getId(),
|
"id" => $liker->getId(),
|
||||||
"url" => $liker->getURL(),
|
"url" => $liker->getURL(),
|
||||||
|
@ -58,17 +66,17 @@ class Wall implements Handler
|
||||||
"avatar" => $liker->getAvatarURL(),
|
"avatar" => $liker->getAvatarURL(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$res->created = (string) $post->getPublicationTime();
|
$res->created = (string) $post->getPublicationTime();
|
||||||
$res->canPin = $post->canBePinnedBy($this->user);
|
$res->canPin = $post->canBePinnedBy($this->user);
|
||||||
$res->canEdit = $res->canDelete = $post->canBeDeletedBy($this->user);
|
$res->canEdit = $res->canDelete = $post->canBeDeletedBy($this->user);
|
||||||
|
|
||||||
$resolve((array) $res);
|
$resolve((array) $res);
|
||||||
}
|
}
|
||||||
|
|
||||||
function newStatus(string $text, callable $resolve, callable $reject): void
|
public function newStatus(string $text, callable $resolve, callable $reject): void
|
||||||
{
|
{
|
||||||
$post = new Post;
|
$post = new Post();
|
||||||
$post->setOwner($this->user->getId());
|
$post->setOwner($this->user->getId());
|
||||||
$post->setWall($this->user->getId());
|
$post->setWall($this->user->getId());
|
||||||
$post->setCreated(time());
|
$post->setCreated(time());
|
||||||
|
@ -77,7 +85,7 @@ class Wall implements Handler
|
||||||
$post->setFlags(0);
|
$post->setFlags(0);
|
||||||
$post->setNsfw(false);
|
$post->setNsfw(false);
|
||||||
$post->save();
|
$post->save();
|
||||||
|
|
||||||
$resolve($post->getId());
|
$resolve($post->getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Exceptions;
|
namespace openvk\VKAPI\Exceptions;
|
||||||
|
|
||||||
class APIErrorException extends \Exception
|
class APIErrorException extends \Exception {}
|
||||||
{}
|
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use openvk\Web\Models\Exceptions\InvalidUserNameException;
|
use openvk\Web\Models\Exceptions\InvalidUserNameException;
|
||||||
|
|
||||||
final class Account extends VKAPIRequestHandler
|
final class Account extends VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
function getProfileInfo(): object
|
public function getProfileInfo(): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$user = $this->getUser();
|
$user = $this->getUser();
|
||||||
|
@ -29,13 +33,14 @@ final class Account extends VKAPIRequestHandler
|
||||||
];
|
];
|
||||||
|
|
||||||
$audio_status = $user->getCurrentAudioStatus();
|
$audio_status = $user->getCurrentAudioStatus();
|
||||||
if(!is_null($audio_status))
|
if (!is_null($audio_status)) {
|
||||||
$return_object->audio_status = $audio_status->toVkApiStruct($user);
|
$return_object->audio_status = $audio_status->toVkApiStruct($user);
|
||||||
|
}
|
||||||
|
|
||||||
return $return_object;
|
return $return_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInfo(): object
|
public function getInfo(): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
|
@ -50,58 +55,58 @@ final class Account extends VKAPIRequestHandler
|
||||||
"is_new_live_streaming_enabled" => false,
|
"is_new_live_streaming_enabled" => false,
|
||||||
"lang" => 1,
|
"lang" => 1,
|
||||||
"no_wall_replies" => 0,
|
"no_wall_replies" => 0,
|
||||||
"own_posts_default" => 0
|
"own_posts_default" => 0,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function setOnline(): int
|
public function setOnline(): int
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$this->getUser()->updOnline($this->getPlatform());
|
$this->getUser()->updOnline($this->getPlatform());
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setOffline(): int
|
public function setOffline(): int
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
# Цiй метод є заглушка
|
# Цiй метод є заглушка
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAppPermissions(): int
|
public function getAppPermissions(): int
|
||||||
{
|
{
|
||||||
return 9355263;
|
return 9355263;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCounters(string $filter = ""): object
|
public function getCounters(string $filter = ""): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
"friends" => $this->getUser()->getFollowersCount(),
|
"friends" => $this->getUser()->getFollowersCount(),
|
||||||
"notifications" => $this->getUser()->getNotificationsCount(),
|
"notifications" => $this->getUser()->getNotificationsCount(),
|
||||||
"messages" => $this->getUser()->getUnreadMessagesCount()
|
"messages" => $this->getUser()->getUnreadMessagesCount(),
|
||||||
];
|
];
|
||||||
|
|
||||||
# TODO: Filter
|
# TODO: Filter
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveProfileInfo(string $first_name = "", string $last_name = "", string $screen_name = "", int $sex = -1, int $relation = -1, string $bdate = "", int $bdate_visibility = -1, string $home_town = "", string $status = ""): object
|
public function saveProfileInfo(string $first_name = "", string $last_name = "", string $screen_name = "", int $sex = -1, int $relation = -1, string $bdate = "", int $bdate_visibility = -1, string $home_town = "", string $status = ""): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$user = $this->getUser();
|
$user = $this->getUser();
|
||||||
|
|
||||||
$output = [
|
$output = [
|
||||||
"changed" => 0,
|
"changed" => 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
if(!empty($first_name) || !empty($last_name)) {
|
if (!empty($first_name) || !empty($last_name)) {
|
||||||
$output["name_request"] = [
|
$output["name_request"] = [
|
||||||
"id" => random_int(1, 2048), # For compatibility with original VK API
|
"id" => random_int(1, 2048), # For compatibility with original VK API
|
||||||
"status" => "success",
|
"status" => "success",
|
||||||
|
@ -110,37 +115,44 @@ final class Account extends VKAPIRequestHandler
|
||||||
];
|
];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if(!empty($first_name))
|
if (!empty($first_name)) {
|
||||||
$user->setFirst_name($first_name);
|
$user->setFirst_name($first_name);
|
||||||
if(!empty($last_name))
|
}
|
||||||
|
if (!empty($last_name)) {
|
||||||
$user->setLast_Name($last_name);
|
$user->setLast_Name($last_name);
|
||||||
|
}
|
||||||
} catch (InvalidUserNameException $e) {
|
} catch (InvalidUserNameException $e) {
|
||||||
$output["name_request"]["status"] = "declined";
|
$output["name_request"]["status"] = "declined";
|
||||||
return (object) $output;
|
return (object) $output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!empty($screen_name))
|
if (!empty($screen_name)) {
|
||||||
if (!$user->setShortCode($screen_name))
|
if (!$user->setShortCode($screen_name)) {
|
||||||
$this->fail(1260, "Invalid screen name");
|
$this->fail(1260, "Invalid screen name");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# For compatibility with original VK API
|
# For compatibility with original VK API
|
||||||
if($sex > 0)
|
if ($sex > 0) {
|
||||||
$user->setSex($sex == 1 ? 1 : 0);
|
$user->setSex($sex == 1 ? 1 : 0);
|
||||||
|
}
|
||||||
if($relation > -1)
|
|
||||||
$user->setMarital_Status($relation);
|
|
||||||
|
|
||||||
if(!empty($bdate)) {
|
if ($relation > -1) {
|
||||||
|
$user->setMarital_Status($relation);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($bdate)) {
|
||||||
$birthday = strtotime($bdate);
|
$birthday = strtotime($bdate);
|
||||||
if (!is_int($birthday))
|
if (!is_int($birthday)) {
|
||||||
$this->fail(100, "invalid value of bdate.");
|
$this->fail(100, "invalid value of bdate.");
|
||||||
|
}
|
||||||
|
|
||||||
$user->setBirthday($birthday);
|
$user->setBirthday($birthday);
|
||||||
}
|
}
|
||||||
|
|
||||||
# For compatibility with original VK API
|
# For compatibility with original VK API
|
||||||
switch($bdate_visibility) {
|
switch ($bdate_visibility) {
|
||||||
case 0:
|
case 0:
|
||||||
$this->fail(946, "Hiding date of birth is not implemented.");
|
$this->fail(946, "Hiding date of birth is not implemented.");
|
||||||
break;
|
break;
|
||||||
|
@ -150,14 +162,16 @@ final class Account extends VKAPIRequestHandler
|
||||||
case 2:
|
case 2:
|
||||||
$user->setBirthday_privacy(1);
|
$user->setBirthday_privacy(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!empty($home_town))
|
|
||||||
$user->setHometown($home_town);
|
|
||||||
|
|
||||||
if(!empty($status))
|
if (!empty($home_town)) {
|
||||||
|
$user->setHometown($home_town);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($status)) {
|
||||||
$user->setStatus($status);
|
$user->setStatus($status);
|
||||||
|
}
|
||||||
if($sex > 0 || $relation > -1 || $bdate_visibility > 1 || !empty("$first_name$last_name$screen_name$bdate$home_town$status")) {
|
|
||||||
|
if ($sex > 0 || $relation > -1 || $bdate_visibility > 1 || !empty("$first_name$last_name$screen_name$bdate$home_town$status")) {
|
||||||
$output["changed"] = 1;
|
$output["changed"] = 1;
|
||||||
$user->save();
|
$user->save();
|
||||||
}
|
}
|
||||||
|
@ -165,21 +179,22 @@ final class Account extends VKAPIRequestHandler
|
||||||
return (object) $output;
|
return (object) $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBalance(): object
|
public function getBalance(): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
if(!OPENVK_ROOT_CONF['openvk']['preferences']['commerce'])
|
if (!OPENVK_ROOT_CONF['openvk']['preferences']['commerce']) {
|
||||||
$this->fail(105, "Commerce is disabled on this instance");
|
$this->fail(105, "Commerce is disabled on this instance");
|
||||||
|
}
|
||||||
|
|
||||||
return (object) ['votes' => $this->getUser()->getCoins()];
|
return (object) ['votes' => $this->getUser()->getCoins()];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOvkSettings(): object
|
public function getOvkSettings(): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$user = $this->getUser();
|
$user = $this->getUser();
|
||||||
|
|
||||||
$settings_list = (object)[
|
$settings_list = (object) [
|
||||||
'avatar_style' => $user->getStyleAvatar(),
|
'avatar_style' => $user->getStyleAvatar(),
|
||||||
'style' => $user->getStyle(),
|
'style' => $user->getStyle(),
|
||||||
'show_rating' => !$user->prefersNotToSeeRating(),
|
'show_rating' => !$user->prefersNotToSeeRating(),
|
||||||
|
@ -191,32 +206,39 @@ final class Account extends VKAPIRequestHandler
|
||||||
return $settings_list;
|
return $settings_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendVotes(int $receiver, int $value, string $message = ""): object
|
public function sendVotes(int $receiver, int $value, string $message = ""): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
if(!OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"])
|
if (!OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"]) {
|
||||||
$this->fail(-105, "Commerce is disabled on this instance");
|
$this->fail(-105, "Commerce is disabled on this instance");
|
||||||
|
}
|
||||||
|
|
||||||
if($receiver < 0)
|
if ($receiver < 0) {
|
||||||
$this->fail(-248, "Invalid receiver id");
|
$this->fail(-248, "Invalid receiver id");
|
||||||
|
}
|
||||||
|
|
||||||
if($value < 1)
|
if ($value < 1) {
|
||||||
$this->fail(-248, "Invalid value");
|
$this->fail(-248, "Invalid value");
|
||||||
|
}
|
||||||
|
|
||||||
if(iconv_strlen($message) > 255)
|
if (iconv_strlen($message) > 255) {
|
||||||
$this->fail(-249, "Message is too long");
|
$this->fail(-249, "Message is too long");
|
||||||
|
}
|
||||||
|
|
||||||
if($this->getUser()->getCoins() < $value)
|
if ($this->getUser()->getCoins() < $value) {
|
||||||
$this->fail(-252, "Not enough votes");
|
$this->fail(-252, "Not enough votes");
|
||||||
|
}
|
||||||
|
|
||||||
$receiver_entity = (new \openvk\Web\Models\Repositories\Users)->get($receiver);
|
$receiver_entity = (new \openvk\Web\Models\Repositories\Users())->get($receiver);
|
||||||
if(!$receiver_entity || $receiver_entity->isDeleted() || !$receiver_entity->canBeViewedBy($this->getUser()))
|
if (!$receiver_entity || $receiver_entity->isDeleted() || !$receiver_entity->canBeViewedBy($this->getUser())) {
|
||||||
$this->fail(-250, "Invalid receiver");
|
$this->fail(-250, "Invalid receiver");
|
||||||
|
}
|
||||||
|
|
||||||
if($receiver_entity->getId() === $this->getUser()->getId())
|
if ($receiver_entity->getId() === $this->getUser()->getId()) {
|
||||||
$this->fail(-251, "Can't transfer votes to yourself");
|
$this->fail(-251, "Can't transfer votes to yourself");
|
||||||
|
}
|
||||||
|
|
||||||
$this->getUser()->setCoins($this->getUser()->getCoins() - $value);
|
$this->getUser()->setCoins($this->getUser()->getCoins() - $value);
|
||||||
$this->getUser()->save();
|
$this->getUser()->save();
|
||||||
|
@ -229,116 +251,126 @@ final class Account extends VKAPIRequestHandler
|
||||||
return (object) ['votes' => $this->getUser()->getCoins()];
|
return (object) ['votes' => $this->getUser()->getCoins()];
|
||||||
}
|
}
|
||||||
|
|
||||||
function ban(int $owner_id): int
|
public function ban(int $owner_id): int
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
if($owner_id < 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if($owner_id == $this->getUser()->getId())
|
if ($owner_id < 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($owner_id == $this->getUser()->getId()) {
|
||||||
$this->fail(15, "Access denied: cannot blacklist yourself");
|
$this->fail(15, "Access denied: cannot blacklist yourself");
|
||||||
|
}
|
||||||
|
|
||||||
$config_limit = OPENVK_ROOT_CONF['openvk']['preferences']['blacklists']['limit'] ?? 100;
|
$config_limit = OPENVK_ROOT_CONF['openvk']['preferences']['blacklists']['limit'] ?? 100;
|
||||||
$user_blocks = $this->getUser()->getBlacklistSize();
|
$user_blocks = $this->getUser()->getBlacklistSize();
|
||||||
if(($user_blocks + 1) > $config_limit)
|
if (($user_blocks + 1) > $config_limit) {
|
||||||
$this->fail(-7856, "Blacklist limit exceeded");
|
$this->fail(-7856, "Blacklist limit exceeded");
|
||||||
|
}
|
||||||
|
|
||||||
$entity = get_entity_by_id($owner_id);
|
$entity = get_entity_by_id($owner_id);
|
||||||
if(!$entity || $entity->isDeleted())
|
if (!$entity || $entity->isDeleted()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if($entity->isBlacklistedBy($this->getUser()))
|
if ($entity->isBlacklistedBy($this->getUser())) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
$this->getUser()->addToBlacklist($entity);
|
$this->getUser()->addToBlacklist($entity);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function unban(int $owner_id): int
|
public function unban(int $owner_id): int
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
if($owner_id < 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if($owner_id == $this->getUser()->getId())
|
if ($owner_id < 0) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($owner_id == $this->getUser()->getId()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
$entity = get_entity_by_id($owner_id);
|
$entity = get_entity_by_id($owner_id);
|
||||||
if(!$entity)
|
if (!$entity) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(!$entity->isBlacklistedBy($this->getUser()))
|
if (!$entity->isBlacklistedBy($this->getUser())) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
$this->getUser()->removeFromBlacklist($entity);
|
$this->getUser()->removeFromBlacklist($entity);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBanned(int $offset = 0, int $count = 100, string $fields = ""): object
|
public function getBanned(int $offset = 0, int $count = 100, string $fields = ""): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$result = (object)[
|
$result = (object) [
|
||||||
'count' => $this->getUser()->getBlacklistSize(),
|
'count' => $this->getUser()->getBlacklistSize(),
|
||||||
'items' => [],
|
'items' => [],
|
||||||
];
|
];
|
||||||
$banned = $this->getUser()->getBlacklist($offset, $count);
|
$banned = $this->getUser()->getBlacklist($offset, $count);
|
||||||
foreach($banned as $ban) {
|
foreach ($banned as $ban) {
|
||||||
if(!$ban) continue;
|
if (!$ban) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$result->items[] = $ban->toVkApiStruct($this->getUser(), $fields);
|
$result->items[] = $ban->toVkApiStruct($this->getUser(), $fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveInterestsInfo(
|
public function saveInterestsInfo(
|
||||||
string $interests = NULL,
|
string $interests = null,
|
||||||
string $fav_music = NULL,
|
string $fav_music = null,
|
||||||
string $fav_films = NULL,
|
string $fav_films = null,
|
||||||
string $fav_shows = NULL,
|
string $fav_shows = null,
|
||||||
string $fav_books = NULL,
|
string $fav_books = null,
|
||||||
string $fav_quote = NULL,
|
string $fav_quote = null,
|
||||||
string $fav_games = NULL,
|
string $fav_games = null,
|
||||||
string $about = NULL,
|
string $about = null,
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$user = $this->getUser();
|
$user = $this->getUser();
|
||||||
$changes = 0;
|
$changes = 0;
|
||||||
$changes_array = [
|
$changes_array = [
|
||||||
"interests" => $interests,
|
"interests" => $interests,
|
||||||
"fav_music" => $fav_music,
|
"fav_music" => $fav_music,
|
||||||
"fav_films" => $fav_films,
|
"fav_films" => $fav_films,
|
||||||
"fav_books" => $fav_books,
|
"fav_books" => $fav_books,
|
||||||
"fav_shows" => $fav_shows,
|
"fav_shows" => $fav_shows,
|
||||||
"fav_quote" => $fav_quote,
|
"fav_quote" => $fav_quote,
|
||||||
"fav_games" => $fav_games,
|
"fav_games" => $fav_games,
|
||||||
"about" => $about,
|
"about" => $about,
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach($changes_array as $change_name => $change_value) {
|
foreach ($changes_array as $change_name => $change_value) {
|
||||||
$set_name = "set".ucfirst($change_name);
|
$set_name = "set" . ucfirst($change_name);
|
||||||
$get_name = "get".str_replace("Fav", "Favorite", str_replace("_", "", ucfirst($change_name)));
|
$get_name = "get" . str_replace("Fav", "Favorite", str_replace("_", "", ucfirst($change_name)));
|
||||||
if(!is_null($change_value) && $change_value !== $user->$get_name()) {
|
if (!is_null($change_value) && $change_value !== $user->$get_name()) {
|
||||||
$user->$set_name(ovk_proc_strtr($change_value, 1000));
|
$user->$set_name(ovk_proc_strtr($change_value, 1000));
|
||||||
$changes += 1;
|
$changes += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($changes > 0) {
|
if ($changes > 0) {
|
||||||
$user->save();
|
$user->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
"changed" => (int)($changes > 0),
|
"changed" => (int) ($changes > 0),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use openvk\VKAPI\Handlers\Wall;
|
use openvk\VKAPI\Handlers\Wall;
|
||||||
use openvk\Web\Models\Repositories\Topics as TopicsRepo;
|
use openvk\Web\Models\Repositories\Topics as TopicsRepo;
|
||||||
use openvk\Web\Models\Repositories\Clubs as ClubsRepo;
|
use openvk\Web\Models\Repositories\Clubs as ClubsRepo;
|
||||||
|
@ -11,27 +15,28 @@ use openvk\Web\Models\Entities\{Topic, Comment, User, Photo, Video};
|
||||||
final class Board extends VKAPIRequestHandler
|
final class Board extends VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
# 13/13
|
# 13/13
|
||||||
function addTopic(int $group_id, string $title, string $text = "", bool $from_group = true, string $attachments = "")
|
public function addTopic(int $group_id, string $title, string $text = "", bool $from_group = true, string $attachments = "")
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$club = (new ClubsRepo)->get($group_id);
|
$club = (new ClubsRepo())->get($group_id);
|
||||||
|
|
||||||
if(!$club) {
|
if (!$club) {
|
||||||
$this->fail(403, "Invalid club");
|
$this->fail(403, "Invalid club");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$club->canBeModifiedBy($this->getUser()) && !$club->isEveryoneCanCreateTopics()) {
|
if (!$club->canBeModifiedBy($this->getUser()) && !$club->isEveryoneCanCreateTopics()) {
|
||||||
$this->fail(403, "Access to club denied");
|
$this->fail(403, "Access to club denied");
|
||||||
}
|
}
|
||||||
|
|
||||||
$flags = 0;
|
$flags = 0;
|
||||||
|
|
||||||
if($from_group == true && $club->canBeModifiedBy($this->getUser()))
|
if ($from_group == true && $club->canBeModifiedBy($this->getUser())) {
|
||||||
$flags |= 0b10000000;
|
$flags |= 0b10000000;
|
||||||
|
}
|
||||||
$topic = new Topic;
|
|
||||||
|
$topic = new Topic();
|
||||||
$topic->setGroup($club->getId());
|
$topic->setGroup($club->getId());
|
||||||
$topic->setOwner($this->getUser()->getId());
|
$topic->setOwner($this->getUser()->getId());
|
||||||
$topic->setTitle(ovk_proc_strtr($title, 127));
|
$topic->setTitle(ovk_proc_strtr($title, 127));
|
||||||
|
@ -39,8 +44,8 @@ final class Board extends VKAPIRequestHandler
|
||||||
$topic->setFlags($flags);
|
$topic->setFlags($flags);
|
||||||
$topic->save();
|
$topic->save();
|
||||||
|
|
||||||
if(!empty($text)) {
|
if (!empty($text)) {
|
||||||
$comment = new Comment;
|
$comment = new Comment();
|
||||||
$comment->setOwner($this->getUser()->getId());
|
$comment->setOwner($this->getUser()->getId());
|
||||||
$comment->setModel(get_class($topic));
|
$comment->setModel(get_class($topic));
|
||||||
$comment->setTarget($topic->getId());
|
$comment->setTarget($topic->getId());
|
||||||
|
@ -48,45 +53,51 @@ final class Board extends VKAPIRequestHandler
|
||||||
$comment->setCreated(time());
|
$comment->setCreated(time());
|
||||||
$comment->setFlags($flags);
|
$comment->setFlags($flags);
|
||||||
$comment->save();
|
$comment->save();
|
||||||
|
|
||||||
if(!empty($attachments)) {
|
if (!empty($attachments)) {
|
||||||
$attachmentsArr = explode(",", $attachments);
|
$attachmentsArr = explode(",", $attachments);
|
||||||
# блин а мне это везде копировать типа
|
# блин а мне это везде копировать типа
|
||||||
|
|
||||||
if(sizeof($attachmentsArr) > 10)
|
if (sizeof($attachmentsArr) > 10) {
|
||||||
$this->fail(50, "Error: too many attachments");
|
$this->fail(50, "Error: too many attachments");
|
||||||
|
}
|
||||||
foreach($attachmentsArr as $attac) {
|
|
||||||
$attachmentType = NULL;
|
|
||||||
|
|
||||||
if(str_contains($attac, "photo"))
|
foreach ($attachmentsArr as $attac) {
|
||||||
|
$attachmentType = null;
|
||||||
|
|
||||||
|
if (str_contains($attac, "photo")) {
|
||||||
$attachmentType = "photo";
|
$attachmentType = "photo";
|
||||||
elseif(str_contains($attac, "video"))
|
} elseif (str_contains($attac, "video")) {
|
||||||
$attachmentType = "video";
|
$attachmentType = "video";
|
||||||
else
|
} else {
|
||||||
$this->fail(205, "Unknown attachment type");
|
$this->fail(205, "Unknown attachment type");
|
||||||
|
}
|
||||||
|
|
||||||
$attachment = str_replace($attachmentType, "", $attac);
|
$attachment = str_replace($attachmentType, "", $attac);
|
||||||
|
|
||||||
$attachmentOwner = (int)explode("_", $attachment)[0];
|
$attachmentOwner = (int) explode("_", $attachment)[0];
|
||||||
$attachmentId = (int)end(explode("_", $attachment));
|
$attachmentId = (int) end(explode("_", $attachment));
|
||||||
|
|
||||||
$attacc = NULL;
|
$attacc = null;
|
||||||
|
|
||||||
if($attachmentType == "photo") {
|
if ($attachmentType == "photo") {
|
||||||
$attacc = (new PhotosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId);
|
$attacc = (new PhotosRepo())->getByOwnerAndVID($attachmentOwner, $attachmentId);
|
||||||
if(!$attacc || $attacc->isDeleted())
|
if (!$attacc || $attacc->isDeleted()) {
|
||||||
$this->fail(100, "Photo does not exists");
|
$this->fail(100, "Photo does not exists");
|
||||||
if($attacc->getOwner()->getId() != $this->getUser()->getId())
|
}
|
||||||
|
if ($attacc->getOwner()->getId() != $this->getUser()->getId()) {
|
||||||
$this->fail(43, "You do not have access to this photo");
|
$this->fail(43, "You do not have access to this photo");
|
||||||
|
}
|
||||||
|
|
||||||
$comment->attach($attacc);
|
$comment->attach($attacc);
|
||||||
} elseif($attachmentType == "video") {
|
} elseif ($attachmentType == "video") {
|
||||||
$attacc = (new VideosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId);
|
$attacc = (new VideosRepo())->getByOwnerAndVID($attachmentOwner, $attachmentId);
|
||||||
if(!$attacc || $attacc->isDeleted())
|
if (!$attacc || $attacc->isDeleted()) {
|
||||||
$this->fail(100, "Video does not exists");
|
$this->fail(100, "Video does not exists");
|
||||||
if($attacc->getOwner()->getId() != $this->getUser()->getId())
|
}
|
||||||
|
if ($attacc->getOwner()->getId() != $this->getUser()->getId()) {
|
||||||
$this->fail(43, "You do not have access to this video");
|
$this->fail(43, "You do not have access to this video");
|
||||||
|
}
|
||||||
|
|
||||||
$comment->attach($attacc);
|
$comment->attach($attacc);
|
||||||
}
|
}
|
||||||
|
@ -100,18 +111,18 @@ final class Board extends VKAPIRequestHandler
|
||||||
return $topic->getId();
|
return $topic->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeTopic(int $group_id, int $topic_id)
|
public function closeTopic(int $group_id, int $topic_id)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$topic = (new TopicsRepo)->getTopicById($group_id, $topic_id);
|
$topic = (new TopicsRepo())->getTopicById($group_id, $topic_id);
|
||||||
|
|
||||||
if(!$topic || !$topic->getClub() || !$topic->getClub()->canBeModifiedBy($this->getUser())) {
|
if (!$topic || !$topic->getClub() || !$topic->getClub()->canBeModifiedBy($this->getUser())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$topic->isClosed()) {
|
if (!$topic->isClosed()) {
|
||||||
$topic->setClosed(1);
|
$topic->setClosed(1);
|
||||||
$topic->save();
|
$topic->save();
|
||||||
}
|
}
|
||||||
|
@ -119,31 +130,32 @@ final class Board extends VKAPIRequestHandler
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createComment(int $group_id, int $topic_id, string $message = "", string $attachments = "", bool $from_group = true)
|
public function createComment(int $group_id, int $topic_id, string $message = "", string $attachments = "", bool $from_group = true)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
if(empty($message) && empty($attachments)) {
|
if (empty($message) && empty($attachments)) {
|
||||||
$this->fail(100, "Required parameter 'message' missing.");
|
$this->fail(100, "Required parameter 'message' missing.");
|
||||||
}
|
}
|
||||||
|
|
||||||
$topic = (new TopicsRepo)->getTopicById($group_id, $topic_id);
|
$topic = (new TopicsRepo())->getTopicById($group_id, $topic_id);
|
||||||
|
|
||||||
if(!$topic || $topic->isDeleted() || $topic->isClosed()) {
|
if (!$topic || $topic->isDeleted() || $topic->isClosed()) {
|
||||||
$this->fail(100, "Topic is deleted, closed or invalid.");
|
$this->fail(100, "Topic is deleted, closed or invalid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
$flags = 0;
|
$flags = 0;
|
||||||
|
|
||||||
if($from_group != 0 && !is_null($topic->getClub()) && $topic->getClub()->canBeModifiedBy($this->user))
|
if ($from_group != 0 && !is_null($topic->getClub()) && $topic->getClub()->canBeModifiedBy($this->user)) {
|
||||||
$flags |= 0b10000000;
|
$flags |= 0b10000000;
|
||||||
|
}
|
||||||
|
|
||||||
if(strlen($message) > 300) {
|
if (strlen($message) > 300) {
|
||||||
$this->fail(20, "Comment is too long.");
|
$this->fail(20, "Comment is too long.");
|
||||||
}
|
}
|
||||||
|
|
||||||
$comment = new Comment;
|
$comment = new Comment();
|
||||||
$comment->setOwner($this->getUser()->getId());
|
$comment->setOwner($this->getUser()->getId());
|
||||||
$comment->setModel(get_class($topic));
|
$comment->setModel(get_class($topic));
|
||||||
$comment->setTarget($topic->getId());
|
$comment->setTarget($topic->getId());
|
||||||
|
@ -152,43 +164,49 @@ final class Board extends VKAPIRequestHandler
|
||||||
$comment->setFlags($flags);
|
$comment->setFlags($flags);
|
||||||
$comment->save();
|
$comment->save();
|
||||||
|
|
||||||
if(!empty($attachments)) {
|
if (!empty($attachments)) {
|
||||||
$attachmentsArr = explode(",", $attachments);
|
$attachmentsArr = explode(",", $attachments);
|
||||||
|
|
||||||
if(sizeof($attachmentsArr) > 10)
|
if (sizeof($attachmentsArr) > 10) {
|
||||||
$this->fail(50, "Error: too many attachments");
|
$this->fail(50, "Error: too many attachments");
|
||||||
|
}
|
||||||
foreach($attachmentsArr as $attac) {
|
|
||||||
$attachmentType = NULL;
|
|
||||||
|
|
||||||
if(str_contains($attac, "photo"))
|
foreach ($attachmentsArr as $attac) {
|
||||||
|
$attachmentType = null;
|
||||||
|
|
||||||
|
if (str_contains($attac, "photo")) {
|
||||||
$attachmentType = "photo";
|
$attachmentType = "photo";
|
||||||
elseif(str_contains($attac, "video"))
|
} elseif (str_contains($attac, "video")) {
|
||||||
$attachmentType = "video";
|
$attachmentType = "video";
|
||||||
else
|
} else {
|
||||||
$this->fail(205, "Unknown attachment type");
|
$this->fail(205, "Unknown attachment type");
|
||||||
|
}
|
||||||
|
|
||||||
$attachment = str_replace($attachmentType, "", $attac);
|
$attachment = str_replace($attachmentType, "", $attac);
|
||||||
|
|
||||||
$attachmentOwner = (int)explode("_", $attachment)[0];
|
$attachmentOwner = (int) explode("_", $attachment)[0];
|
||||||
$attachmentId = (int)end(explode("_", $attachment));
|
$attachmentId = (int) end(explode("_", $attachment));
|
||||||
|
|
||||||
$attacc = NULL;
|
$attacc = null;
|
||||||
|
|
||||||
if($attachmentType == "photo") {
|
if ($attachmentType == "photo") {
|
||||||
$attacc = (new PhotosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId);
|
$attacc = (new PhotosRepo())->getByOwnerAndVID($attachmentOwner, $attachmentId);
|
||||||
if(!$attacc || $attacc->isDeleted())
|
if (!$attacc || $attacc->isDeleted()) {
|
||||||
$this->fail(100, "Photo does not exists");
|
$this->fail(100, "Photo does not exists");
|
||||||
if($attacc->getOwner()->getId() != $this->getUser()->getId())
|
}
|
||||||
|
if ($attacc->getOwner()->getId() != $this->getUser()->getId()) {
|
||||||
$this->fail(43, "You do not have access to this photo");
|
$this->fail(43, "You do not have access to this photo");
|
||||||
|
}
|
||||||
|
|
||||||
$comment->attach($attacc);
|
$comment->attach($attacc);
|
||||||
} elseif($attachmentType == "video") {
|
} elseif ($attachmentType == "video") {
|
||||||
$attacc = (new VideosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId);
|
$attacc = (new VideosRepo())->getByOwnerAndVID($attachmentOwner, $attachmentId);
|
||||||
if(!$attacc || $attacc->isDeleted())
|
if (!$attacc || $attacc->isDeleted()) {
|
||||||
$this->fail(100, "Video does not exists");
|
$this->fail(100, "Video does not exists");
|
||||||
if($attacc->getOwner()->getId() != $this->getUser()->getId())
|
}
|
||||||
|
if ($attacc->getOwner()->getId() != $this->getUser()->getId()) {
|
||||||
$this->fail(43, "You do not have access to this video");
|
$this->fail(43, "You do not have access to this video");
|
||||||
|
}
|
||||||
|
|
||||||
$comment->attach($attacc);
|
$comment->attach($attacc);
|
||||||
}
|
}
|
||||||
|
@ -198,29 +216,30 @@ final class Board extends VKAPIRequestHandler
|
||||||
return $comment->getId();
|
return $comment->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteComment(int $comment_id, int $group_id = 0, int $topic_id = 0)
|
public function deleteComment(int $comment_id, int $group_id = 0, int $topic_id = 0)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$comment = (new CommentsRepo)->get($comment_id);
|
$comment = (new CommentsRepo())->get($comment_id);
|
||||||
|
|
||||||
if($comment->isDeleted() || !$comment || !$comment->canBeDeletedBy($this->getUser()))
|
if ($comment->isDeleted() || !$comment || !$comment->canBeDeletedBy($this->getUser())) {
|
||||||
$this->fail(403, "Access to comment denied");
|
$this->fail(403, "Access to comment denied");
|
||||||
|
}
|
||||||
|
|
||||||
$comment->delete();
|
$comment->delete();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteTopic(int $group_id, int $topic_id)
|
public function deleteTopic(int $group_id, int $topic_id)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$topic = (new TopicsRepo)->getTopicById($group_id, $topic_id);
|
$topic = (new TopicsRepo())->getTopicById($group_id, $topic_id);
|
||||||
|
|
||||||
if(!$topic || !$topic->getClub() || $topic->isDeleted() || !$topic->getClub()->canBeModifiedBy($this->getUser())) {
|
if (!$topic || !$topic->getClub() || $topic->isDeleted() || !$topic->getClub()->canBeModifiedBy($this->getUser())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,7 +248,7 @@ final class Board extends VKAPIRequestHandler
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function editComment(int $comment_id, int $group_id = 0, int $topic_id = 0, string $message, string $attachments)
|
public function editComment(int $comment_id, int $group_id = 0, int $topic_id = 0, string $message, string $attachments)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
@ -239,7 +258,7 @@ final class Board extends VKAPIRequestHandler
|
||||||
|
|
||||||
if($comment->getOwner() != $this->getUser()->getId())
|
if($comment->getOwner() != $this->getUser()->getId())
|
||||||
$this->fail(15, "Access to comment denied");
|
$this->fail(15, "Access to comment denied");
|
||||||
|
|
||||||
$comment->setContent($message);
|
$comment->setContent($message);
|
||||||
$comment->setEdited(time());
|
$comment->setEdited(time());
|
||||||
$comment->save();
|
$comment->save();
|
||||||
|
@ -247,14 +266,14 @@ final class Board extends VKAPIRequestHandler
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function editTopic(int $group_id, int $topic_id, string $title)
|
public function editTopic(int $group_id, int $topic_id, string $title)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$topic = (new TopicsRepo)->getTopicById($group_id, $topic_id);
|
$topic = (new TopicsRepo())->getTopicById($group_id, $topic_id);
|
||||||
|
|
||||||
if(!$topic || !$topic->getClub() || $topic->isDeleted() || !$topic->getClub()->canBeModifiedBy($this->getUser())) {
|
if (!$topic || !$topic->getClub() || $topic->isDeleted() || !$topic->getClub()->canBeModifiedBy($this->getUser())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,14 +284,14 @@ final class Board extends VKAPIRequestHandler
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function fixTopic(int $group_id, int $topic_id)
|
public function fixTopic(int $group_id, int $topic_id)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$topic = (new TopicsRepo)->getTopicById($group_id, $topic_id);
|
$topic = (new TopicsRepo())->getTopicById($group_id, $topic_id);
|
||||||
|
|
||||||
if(!$topic || !$topic->getClub() || !$topic->getClub()->canBeModifiedBy($this->getUser())) {
|
if (!$topic || !$topic->getClub() || !$topic->getClub()->canBeModifiedBy($this->getUser())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,31 +302,31 @@ final class Board extends VKAPIRequestHandler
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComments(int $group_id, int $topic_id, bool $need_likes = false, int $start_comment_id = 0, int $offset = 0, int $count = 40, bool $extended = false, string $sort = "asc")
|
public function getComments(int $group_id, int $topic_id, bool $need_likes = false, int $start_comment_id = 0, int $offset = 0, int $count = 40, bool $extended = false, string $sort = "asc")
|
||||||
{
|
{
|
||||||
# start_comment_id ne robit
|
# start_comment_id ne robit
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$topic = (new TopicsRepo)->getTopicById($group_id, $topic_id);
|
|
||||||
|
|
||||||
if(!$topic || !$topic->getClub() || $topic->isDeleted()) {
|
$topic = (new TopicsRepo())->getTopicById($group_id, $topic_id);
|
||||||
|
|
||||||
|
if (!$topic || !$topic->getClub() || $topic->isDeleted()) {
|
||||||
$this->fail(5, "Invalid topic");
|
$this->fail(5, "Invalid topic");
|
||||||
}
|
}
|
||||||
|
|
||||||
$arr = [
|
$arr = [
|
||||||
"items" => []
|
"items" => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
$comms = array_slice(iterator_to_array($topic->getComments(1, $count + $offset)), $offset);
|
$comms = array_slice(iterator_to_array($topic->getComments(1, $count + $offset)), $offset);
|
||||||
foreach($comms as $comm) {
|
foreach ($comms as $comm) {
|
||||||
$arr["items"][] = $this->getApiBoardComment($comm, $need_likes);
|
$arr["items"][] = $this->getApiBoardComment($comm, $need_likes);
|
||||||
|
|
||||||
if($extended) {
|
if ($extended) {
|
||||||
if($comm->getOwner() instanceof \openvk\Web\Models\Entities\User) {
|
if ($comm->getOwner() instanceof \openvk\Web\Models\Entities\User) {
|
||||||
$arr["profiles"][] = $comm->getOwner()->toVkApiStruct();
|
$arr["profiles"][] = $comm->getOwner()->toVkApiStruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
if($comm->getOwner() instanceof \openvk\Web\Models\Entities\Club) {
|
if ($comm->getOwner() instanceof \openvk\Web\Models\Entities\Club) {
|
||||||
$arr["groups"][] = $comm->getOwner()->toVkApiStruct();
|
$arr["groups"][] = $comm->getOwner()->toVkApiStruct();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,34 +335,36 @@ final class Board extends VKAPIRequestHandler
|
||||||
return $arr;
|
return $arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTopics(int $group_id, string $topic_ids = "", int $order = 1, int $offset = 0, int $count = 40, bool $extended = false, int $preview = 0, int $preview_length = 90)
|
public function getTopics(int $group_id, string $topic_ids = "", int $order = 1, int $offset = 0, int $count = 40, bool $extended = false, int $preview = 0, int $preview_length = 90)
|
||||||
{
|
{
|
||||||
# order и extended ничё не делают
|
# order и extended ничё не делают
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$arr = [];
|
$arr = [];
|
||||||
$club = (new ClubsRepo)->get($group_id);
|
$club = (new ClubsRepo())->get($group_id);
|
||||||
|
|
||||||
$topics = array_slice(iterator_to_array((new TopicsRepo)->getClubTopics($club, 1, $count + $offset)), $offset);
|
$topics = array_slice(iterator_to_array((new TopicsRepo())->getClubTopics($club, 1, $count + $offset)), $offset);
|
||||||
$arr["count"] = (new TopicsRepo)->getClubTopicsCount($club);
|
$arr["count"] = (new TopicsRepo())->getClubTopicsCount($club);
|
||||||
$arr["items"] = [];
|
$arr["items"] = [];
|
||||||
$arr["default_order"] = $order;
|
$arr["default_order"] = $order;
|
||||||
$arr["can_add_topics"] = $club->canBeModifiedBy($this->getUser()) ? true : ($club->isEveryoneCanCreateTopics() ? true : false);
|
$arr["can_add_topics"] = $club->canBeModifiedBy($this->getUser()) ? true : ($club->isEveryoneCanCreateTopics() ? true : false);
|
||||||
$arr["profiles"] = [];
|
$arr["profiles"] = [];
|
||||||
|
|
||||||
if(empty($topic_ids)) {
|
if (empty($topic_ids)) {
|
||||||
foreach($topics as $topic) {
|
foreach ($topics as $topic) {
|
||||||
if($topic->isDeleted()) continue;
|
if ($topic->isDeleted()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$arr["items"][] = $topic->toVkApiStruct($preview, $preview_length > 1 ? $preview_length : 90);
|
$arr["items"][] = $topic->toVkApiStruct($preview, $preview_length > 1 ? $preview_length : 90);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$topics = explode(',', $topic_ids);
|
$topics = explode(',', $topic_ids);
|
||||||
|
|
||||||
foreach($topics as $topic) {
|
foreach ($topics as $topic) {
|
||||||
$id = explode("_", $topic);
|
$id = explode("_", $topic);
|
||||||
$topicy = (new TopicsRepo)->getTopicById((int)$id[0], (int)$id[1]);
|
$topicy = (new TopicsRepo())->getTopicById((int) $id[0], (int) $id[1]);
|
||||||
|
|
||||||
if($topicy && !$topicy->isDeleted()) {
|
if ($topicy && !$topicy->isDeleted()) {
|
||||||
$arr["items"][] = $topicy->toVkApiStruct($preview, $preview_length > 1 ? $preview_length : 90);
|
$arr["items"][] = $topicy->toVkApiStruct($preview, $preview_length > 1 ? $preview_length : 90);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,18 +373,18 @@ final class Board extends VKAPIRequestHandler
|
||||||
return $arr;
|
return $arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function openTopic(int $group_id, int $topic_id)
|
public function openTopic(int $group_id, int $topic_id)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$topic = (new TopicsRepo)->getTopicById($group_id, $topic_id);
|
$topic = (new TopicsRepo())->getTopicById($group_id, $topic_id);
|
||||||
|
|
||||||
if(!$topic || !$topic->getClub() || !$topic->isDeleted() || !$topic->getClub()->canBeModifiedBy($this->getUser())) {
|
if (!$topic || !$topic->getClub() || !$topic->isDeleted() || !$topic->getClub()->canBeModifiedBy($this->getUser())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($topic->isClosed()) {
|
if ($topic->isClosed()) {
|
||||||
$topic->setClosed(0);
|
$topic->setClosed(0);
|
||||||
$topic->save();
|
$topic->save();
|
||||||
}
|
}
|
||||||
|
@ -371,23 +392,23 @@ final class Board extends VKAPIRequestHandler
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function restoreComment(int $group_id, int $topic_id, int $comment_id)
|
public function restoreComment(int $group_id, int $topic_id, int $comment_id)
|
||||||
{
|
{
|
||||||
$this->fail(501, "Not implemented");
|
$this->fail(501, "Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
function unfixTopic(int $group_id, int $topic_id)
|
public function unfixTopic(int $group_id, int $topic_id)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$topic = (new TopicsRepo)->getTopicById($group_id, $topic_id);
|
$topic = (new TopicsRepo())->getTopicById($group_id, $topic_id);
|
||||||
|
|
||||||
if(!$topic || !$topic->getClub() || !$topic->getClub()->canBeModifiedBy($this->getUser())) {
|
if (!$topic || !$topic->getClub() || !$topic->getClub()->canBeModifiedBy($this->getUser())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($topic->isPinned()) {
|
if ($topic->isPinned()) {
|
||||||
$topic->setClosed(0);
|
$topic->setClosed(0);
|
||||||
$topic->save();
|
$topic->save();
|
||||||
}
|
}
|
||||||
|
@ -409,21 +430,22 @@ final class Board extends VKAPIRequestHandler
|
||||||
$res->text = $comment->getText(false);
|
$res->text = $comment->getText(false);
|
||||||
$res->attachments = [];
|
$res->attachments = [];
|
||||||
$res->likes = [];
|
$res->likes = [];
|
||||||
if($need_likes) {
|
if ($need_likes) {
|
||||||
$res->likes = [
|
$res->likes = [
|
||||||
"count" => $comment->getLikesCount(),
|
"count" => $comment->getLikesCount(),
|
||||||
"user_likes" => (int) $comment->hasLikeFrom($this->getUser()),
|
"user_likes" => (int) $comment->hasLikeFrom($this->getUser()),
|
||||||
"can_like" => 1 # а чё типо не может ахахаххахах
|
"can_like" => 1, # а чё типо не может ахахаххахах
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($comment->getChildren() as $attachment) {
|
foreach ($comment->getChildren() as $attachment) {
|
||||||
if($attachment->isDeleted())
|
if ($attachment->isDeleted()) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$res->attachments[] = $attachment->toVkApiStruct();
|
$res->attachments[] = $attachment->toVkApiStruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,48 +1,57 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use Chandler\Database\DatabaseConnection;
|
use Chandler\Database\DatabaseConnection;
|
||||||
use openvk\Web\Models\Entities\Document;
|
use openvk\Web\Models\Entities\Document;
|
||||||
use openvk\Web\Models\Repositories\Documents;
|
use openvk\Web\Models\Repositories\Documents;
|
||||||
|
|
||||||
final class Docs extends VKAPIRequestHandler
|
final class Docs extends VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
function add(int $owner_id, int $doc_id, ?string $access_key): string
|
public function add(int $owner_id, int $doc_id, ?string $access_key): string
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$doc = (new Documents)->getDocumentById($owner_id, $doc_id, $access_key);
|
$doc = (new Documents())->getDocumentById($owner_id, $doc_id, $access_key);
|
||||||
if(!$doc || $doc->isDeleted())
|
if (!$doc || $doc->isDeleted()) {
|
||||||
$this->fail(1150, "Invalid document id");
|
$this->fail(1150, "Invalid document id");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$doc->checkAccessKey($access_key))
|
if (!$doc->checkAccessKey($access_key)) {
|
||||||
$this->fail(15, "Access denied");
|
$this->fail(15, "Access denied");
|
||||||
|
}
|
||||||
|
|
||||||
if($doc->isCopiedBy($this->getUser()))
|
if ($doc->isCopiedBy($this->getUser())) {
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: this document already added");
|
$this->fail(100, "One of the parameters specified was missing or invalid: this document already added");
|
||||||
|
}
|
||||||
|
|
||||||
$new_doc = $doc->copy($this->getUser());
|
$new_doc = $doc->copy($this->getUser());
|
||||||
|
|
||||||
return $new_doc->getPrettyId();
|
return $new_doc->getPrettyId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete(int $owner_id, int $doc_id): int
|
public function delete(int $owner_id, int $doc_id): int
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
$doc = (new Documents)->getDocumentByIdUnsafe($owner_id, $doc_id);
|
$doc = (new Documents())->getDocumentByIdUnsafe($owner_id, $doc_id);
|
||||||
if(!$doc || $doc->isDeleted())
|
if (!$doc || $doc->isDeleted()) {
|
||||||
$this->fail(1150, "Invalid document id");
|
$this->fail(1150, "Invalid document id");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$doc->canBeModifiedBy($this->getUser()))
|
if (!$doc->canBeModifiedBy($this->getUser())) {
|
||||||
$this->fail(1153, "Access to document is denied");
|
$this->fail(1153, "Access to document is denied");
|
||||||
|
}
|
||||||
|
|
||||||
$doc->delete();
|
$doc->delete();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function restore(int $owner_id, int $doc_id): int
|
public function restore(int $owner_id, int $doc_id): int
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
@ -50,77 +59,87 @@ final class Docs extends VKAPIRequestHandler
|
||||||
return $this->add($owner_id, $doc_id, "");
|
return $this->add($owner_id, $doc_id, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
function edit(int $owner_id, int $doc_id, ?string $title = "", ?string $tags = "", ?int $folder_id = 0, int $owner_hidden = -1): int
|
public function edit(int $owner_id, int $doc_id, ?string $title = "", ?string $tags = "", ?int $folder_id = 0, int $owner_hidden = -1): int
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$doc = (new Documents)->getDocumentByIdUnsafe($owner_id, $doc_id);
|
$doc = (new Documents())->getDocumentByIdUnsafe($owner_id, $doc_id);
|
||||||
if(!$doc || $doc->isDeleted())
|
if (!$doc || $doc->isDeleted()) {
|
||||||
$this->fail(1150, "Invalid document id");
|
$this->fail(1150, "Invalid document id");
|
||||||
if(!$doc->canBeModifiedBy($this->getUser()))
|
}
|
||||||
|
if (!$doc->canBeModifiedBy($this->getUser())) {
|
||||||
$this->fail(1153, "Access to document is denied");
|
$this->fail(1153, "Access to document is denied");
|
||||||
if(iconv_strlen($title ?? "") > 128 || iconv_strlen($title ?? "") < 0)
|
}
|
||||||
|
if (iconv_strlen($title ?? "") > 128 || iconv_strlen($title ?? "") < 0) {
|
||||||
$this->fail(1152, "Invalid document title");
|
$this->fail(1152, "Invalid document title");
|
||||||
if(iconv_strlen($tags ?? "") > 256)
|
}
|
||||||
|
if (iconv_strlen($tags ?? "") > 256) {
|
||||||
$this->fail(1154, "Invalid tags");
|
$this->fail(1154, "Invalid tags");
|
||||||
|
}
|
||||||
|
|
||||||
if($title)
|
if ($title) {
|
||||||
$doc->setName($title);
|
$doc->setName($title);
|
||||||
|
}
|
||||||
|
|
||||||
$doc->setTags($tags);
|
$doc->setTags($tags);
|
||||||
if(in_array($folder_id, [0, 3]))
|
if (in_array($folder_id, [0, 3])) {
|
||||||
$doc->setFolder_id($folder_id);
|
$doc->setFolder_id($folder_id);
|
||||||
if(in_array($owner_hidden, [0, 1]))
|
}
|
||||||
|
if (in_array($owner_hidden, [0, 1])) {
|
||||||
$doc->setOwner_hidden($owner_hidden);
|
$doc->setOwner_hidden($owner_hidden);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$doc->setEdited(time());
|
$doc->setEdited(time());
|
||||||
$doc->save();
|
$doc->save();
|
||||||
} catch(\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(int $count = 30, int $offset = 0, int $type = -1, int $owner_id = NULL, int $return_tags = 0, int $order = 0): object
|
public function get(int $count = 30, int $offset = 0, int $type = -1, int $owner_id = null, int $return_tags = 0, int $order = 0): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
if(!$owner_id)
|
if (!$owner_id) {
|
||||||
$owner_id = $this->getUser()->getId();
|
$owner_id = $this->getUser()->getId();
|
||||||
|
}
|
||||||
if($owner_id > 0 && $owner_id != $this->getUser()->getId())
|
|
||||||
$this->fail(15, "Access denied");
|
|
||||||
|
|
||||||
$documents = (new Documents)->getDocumentsByOwner($owner_id, $order, $type);
|
if ($owner_id > 0 && $owner_id != $this->getUser()->getId()) {
|
||||||
$res = (object)[
|
$this->fail(15, "Access denied");
|
||||||
|
}
|
||||||
|
|
||||||
|
$documents = (new Documents())->getDocumentsByOwner($owner_id, $order, $type);
|
||||||
|
$res = (object) [
|
||||||
"count" => $documents->size(),
|
"count" => $documents->size(),
|
||||||
"items" => [],
|
"items" => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach($documents->offsetLimit($offset, $count) as $doc) {
|
foreach ($documents->offsetLimit($offset, $count) as $doc) {
|
||||||
$res->items[] = $doc->toVkApiStruct($this->getUser(), $return_tags == 1);
|
$res->items[] = $doc->toVkApiStruct($this->getUser(), $return_tags == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getById(string $docs, int $return_tags = 0): array
|
public function getById(string $docs, int $return_tags = 0): array
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$item_ids = explode(",", $docs);
|
$item_ids = explode(",", $docs);
|
||||||
$response = [];
|
$response = [];
|
||||||
if(sizeof($item_ids) < 1) {
|
if (sizeof($item_ids) < 1) {
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: docs is undefined");
|
$this->fail(100, "One of the parameters specified was missing or invalid: docs is undefined");
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($item_ids as $id) {
|
foreach ($item_ids as $id) {
|
||||||
$splitted_id = explode("_", $id);
|
$splitted_id = explode("_", $id);
|
||||||
$doc = (new Documents)->getDocumentById((int)$splitted_id[0], (int)$splitted_id[1], $splitted_id[2]);
|
$doc = (new Documents())->getDocumentById((int) $splitted_id[0], (int) $splitted_id[1], $splitted_id[2]);
|
||||||
if(!$doc || $doc->isDeleted())
|
if (!$doc || $doc->isDeleted()) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$response[] = $doc->toVkApiStruct($this->getUser(), $return_tags === 1);
|
$response[] = $doc->toVkApiStruct($this->getUser(), $return_tags === 1);
|
||||||
}
|
}
|
||||||
|
@ -128,76 +147,76 @@ final class Docs extends VKAPIRequestHandler
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTypes(?int $owner_id)
|
public function getTypes(?int $owner_id)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
if(!$owner_id)
|
if (!$owner_id) {
|
||||||
$owner_id = $this->getUser()->getId();
|
$owner_id = $this->getUser()->getId();
|
||||||
|
}
|
||||||
if($owner_id > 0 && $owner_id != $this->getUser()->getId())
|
|
||||||
|
if ($owner_id > 0 && $owner_id != $this->getUser()->getId()) {
|
||||||
$this->fail(15, "Access denied");
|
$this->fail(15, "Access denied");
|
||||||
|
}
|
||||||
$types = (new Documents)->getTypes($owner_id);
|
|
||||||
|
$types = (new Documents())->getTypes($owner_id);
|
||||||
return [
|
return [
|
||||||
"count" => sizeof($types),
|
"count" => sizeof($types),
|
||||||
"items" => $types,
|
"items" => $types,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTags(?int $owner_id, ?int $type = 0)
|
public function getTags(?int $owner_id, ?int $type = 0)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
if(!$owner_id)
|
if (!$owner_id) {
|
||||||
$owner_id = $this->getUser()->getId();
|
$owner_id = $this->getUser()->getId();
|
||||||
|
}
|
||||||
if($owner_id > 0 && $owner_id != $this->getUser()->getId())
|
|
||||||
|
if ($owner_id > 0 && $owner_id != $this->getUser()->getId()) {
|
||||||
$this->fail(15, "Access denied");
|
$this->fail(15, "Access denied");
|
||||||
|
}
|
||||||
$tags = (new Documents)->getTags($owner_id, $type);
|
|
||||||
|
$tags = (new Documents())->getTags($owner_id, $type);
|
||||||
return $tags;
|
return $tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
function search(string $q = "", int $search_own = -1, int $order = -1, int $count = 30, int $offset = 0, int $return_tags = 0, int $type = 0, ?string $tags = NULL): object
|
public function search(string $q = "", int $search_own = -1, int $order = -1, int $count = 30, int $offset = 0, int $return_tags = 0, int $type = 0, ?string $tags = null): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$params = [];
|
$params = [];
|
||||||
$o_order = ["type" => "id", "invert" => false];
|
$o_order = ["type" => "id", "invert" => false];
|
||||||
|
|
||||||
if(iconv_strlen($q) > 512)
|
if (iconv_strlen($q) > 512) {
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: q should be not more 512 letters length");
|
$this->fail(100, "One of the parameters specified was missing or invalid: q should be not more 512 letters length");
|
||||||
|
}
|
||||||
|
|
||||||
if(in_array($type, [1,2,3,4,5,6,7,8]))
|
if (in_array($type, [1,2,3,4,5,6,7,8])) {
|
||||||
$params["type"] = $type;
|
$params["type"] = $type;
|
||||||
|
}
|
||||||
|
|
||||||
if(iconv_strlen($tags ?? "") < 512)
|
if (iconv_strlen($tags ?? "") < 512) {
|
||||||
$params["tags"] = $tags;
|
$params["tags"] = $tags;
|
||||||
|
}
|
||||||
|
|
||||||
if($search_own === 1)
|
if ($search_own === 1) {
|
||||||
$params["from_me"] = $this->getUser()->getId();
|
$params["from_me"] = $this->getUser()->getId();
|
||||||
|
}
|
||||||
|
|
||||||
$documents = (new Documents)->find($q, $params, $o_order);
|
$documents = (new Documents())->find($q, $params, $o_order);
|
||||||
$res = (object)[
|
$res = (object) [
|
||||||
"count" => $documents->size(),
|
"count" => $documents->size(),
|
||||||
"items" => [],
|
"items" => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach($documents->offsetLimit($offset, $count) as $doc) {
|
foreach ($documents->offsetLimit($offset, $count) as $doc) {
|
||||||
$res->items[] = $doc->toVkApiStruct($this->getUser(), $return_tags == 1);
|
$res->items[] = $doc->toVkApiStruct($this->getUser(), $return_tags == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUploadServer(?int $group_id = NULL)
|
public function getUploadServer(?int $group_id = null)
|
||||||
{
|
|
||||||
$this->requireUser();
|
|
||||||
$this->willExecuteWriteAction();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWallUploadServer(?int $group_id = NULL)
|
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
@ -205,7 +224,15 @@ final class Docs extends VKAPIRequestHandler
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function save(string $file, string $title, string $tags, ?int $return_tags = 0)
|
public function getWallUploadServer(?int $group_id = null)
|
||||||
|
{
|
||||||
|
$this->requireUser();
|
||||||
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save(string $file, string $title, string $tags, ?int $return_tags = 0)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
|
@ -1,188 +1,195 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
||||||
|
|
||||||
final class Friends extends VKAPIRequestHandler
|
final class Friends extends VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
function get(int $user_id = 0, string $fields = "", int $offset = 0, int $count = 100): object
|
public function get(int $user_id = 0, string $fields = "", int $offset = 0, int $count = 100): object
|
||||||
{
|
{
|
||||||
$i = 0;
|
$i = 0;
|
||||||
$offset++;
|
$offset++;
|
||||||
$friends = [];
|
$friends = [];
|
||||||
|
|
||||||
$users = new UsersRepo;
|
$users = new UsersRepo();
|
||||||
|
|
||||||
|
$this->requireUser();
|
||||||
|
|
||||||
|
if ($user_id == 0) {
|
||||||
|
$user_id = $this->getUser()->getId();
|
||||||
|
}
|
||||||
|
|
||||||
$this->requireUser();
|
|
||||||
|
|
||||||
if ($user_id == 0) {
|
|
||||||
$user_id = $this->getUser()->getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = $users->get($user_id);
|
$user = $users->get($user_id);
|
||||||
|
|
||||||
if(!$user || $user->isDeleted())
|
|
||||||
$this->fail(100, "Invalid user");
|
|
||||||
|
|
||||||
if(!$user->getPrivacyPermission("friends.read", $this->getUser()))
|
if (!$user || $user->isDeleted()) {
|
||||||
|
$this->fail(100, "Invalid user");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$user->getPrivacyPermission("friends.read", $this->getUser())) {
|
||||||
$this->fail(15, "Access denied: this user chose to hide his friends.");
|
$this->fail(15, "Access denied: this user chose to hide his friends.");
|
||||||
|
}
|
||||||
foreach($user->getFriends($offset, $count) as $friend) {
|
|
||||||
|
foreach ($user->getFriends($offset, $count) as $friend) {
|
||||||
$friends[$i] = $friend->getId();
|
$friends[$i] = $friend->getId();
|
||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $friends;
|
$response = $friends;
|
||||||
|
|
||||||
$usersApi = new Users($this->getUser());
|
$usersApi = new Users($this->getUser());
|
||||||
|
|
||||||
if(!is_null($fields))
|
if (!is_null($fields)) {
|
||||||
$response = $usersApi->get(implode(',', $friends), $fields, 0, $count); # FIXME
|
$response = $usersApi->get(implode(',', $friends), $fields, 0, $count);
|
||||||
|
} # FIXME
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
"count" => $users->get($user_id)->getFriendsCount(),
|
"count" => $users->get($user_id)->getFriendsCount(),
|
||||||
"items" => $response
|
"items" => $response,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLists(): object
|
public function getLists(): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
"count" => 0,
|
"count" => 0,
|
||||||
"items" => (array)[]
|
"items" => (array) [],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteList(): int
|
public function deleteList(): int
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function edit(): int
|
public function edit(): int
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function editList(): int
|
public function editList(): int
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function add(string $user_id): int
|
public function add(string $user_id): int
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$users = new UsersRepo;
|
$users = new UsersRepo();
|
||||||
$user = $users->get(intval($user_id));
|
$user = $users->get(intval($user_id));
|
||||||
|
|
||||||
if(is_null($user)) {
|
|
||||||
$this->fail(177, "Cannot add this user to friends as user not found");
|
|
||||||
} else if($user->getId() == $this->getUser()->getId()) {
|
|
||||||
$this->fail(174, "Cannot add user himself as friend");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch($user->getSubscriptionStatus($this->getUser())) {
|
if (is_null($user)) {
|
||||||
case 0:
|
$this->fail(177, "Cannot add this user to friends as user not found");
|
||||||
$user->toggleSubscription($this->getUser());
|
} elseif ($user->getId() == $this->getUser()->getId()) {
|
||||||
return 1;
|
$this->fail(174, "Cannot add user himself as friend");
|
||||||
|
}
|
||||||
|
|
||||||
case 1:
|
switch ($user->getSubscriptionStatus($this->getUser())) {
|
||||||
$user->toggleSubscription($this->getUser());
|
case 0:
|
||||||
return 2;
|
$user->toggleSubscription($this->getUser());
|
||||||
|
return 1;
|
||||||
|
|
||||||
case 3:
|
case 1:
|
||||||
return 2;
|
$user->toggleSubscription($this->getUser());
|
||||||
|
return 2;
|
||||||
default:
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function delete(string $user_id): int
|
case 3:
|
||||||
{
|
return 2;
|
||||||
$this->requireUser();
|
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete(string $user_id): int
|
||||||
|
{
|
||||||
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$users = new UsersRepo;
|
$users = new UsersRepo();
|
||||||
|
|
||||||
$user = $users->get(intval($user_id));
|
$user = $users->get(intval($user_id));
|
||||||
|
|
||||||
switch($user->getSubscriptionStatus($this->getUser())) {
|
switch ($user->getSubscriptionStatus($this->getUser())) {
|
||||||
case 3:
|
case 3:
|
||||||
$user->toggleSubscription($this->getUser());
|
$user->toggleSubscription($this->getUser());
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
default:
|
|
||||||
$this->fail(15, "Access denied: No friend or friend request found.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function areFriends(string $user_ids): array
|
default:
|
||||||
{
|
$this->fail(15, "Access denied: No friend or friend request found.");
|
||||||
$this->requireUser();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$users = new UsersRepo;
|
public function areFriends(string $user_ids): array
|
||||||
|
{
|
||||||
|
$this->requireUser();
|
||||||
|
|
||||||
$friends = explode(',', $user_ids);
|
$users = new UsersRepo();
|
||||||
|
|
||||||
$response = [];
|
$friends = explode(',', $user_ids);
|
||||||
|
|
||||||
for($i=0; $i < sizeof($friends); $i++) {
|
$response = [];
|
||||||
$friend = $users->get(intval($friends[$i]));
|
|
||||||
|
|
||||||
$response[] = (object)[
|
for ($i = 0; $i < sizeof($friends); $i++) {
|
||||||
"friend_status" => $friend->getSubscriptionStatus($this->getUser()),
|
$friend = $users->get(intval($friends[$i]));
|
||||||
"user_id" => $friend->getId()
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response;
|
$response[] = (object) [
|
||||||
}
|
"friend_status" => $friend->getSubscriptionStatus($this->getUser()),
|
||||||
|
"user_id" => $friend->getId(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
function getRequests(string $fields = "", int $out = 0, int $offset = 0, int $count = 100, int $extended = 0): object
|
return $response;
|
||||||
{
|
}
|
||||||
if ($count >= 1000)
|
|
||||||
$this->fail(100, "One of the required parameters was not passed or is invalid.");
|
|
||||||
|
|
||||||
$this->requireUser();
|
public function getRequests(string $fields = "", int $out = 0, int $offset = 0, int $count = 100, int $extended = 0): object
|
||||||
|
{
|
||||||
|
if ($count >= 1000) {
|
||||||
|
$this->fail(100, "One of the required parameters was not passed or is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
$i = 0;
|
$this->requireUser();
|
||||||
$offset++;
|
|
||||||
$followers = [];
|
|
||||||
|
|
||||||
if ($out != 0) {
|
$i = 0;
|
||||||
foreach($this->getUser()->getFollowers($offset, $count) as $follower) {
|
$offset++;
|
||||||
$followers[$i] = $follower->getId();
|
$followers = [];
|
||||||
$i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach($this->getUser()->getRequests($offset, $count) as $follower) {
|
|
||||||
$followers[$i] = $follower->getId();
|
|
||||||
$i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$response = $followers;
|
if ($out != 0) {
|
||||||
$usersApi = new Users($this->getUser());
|
foreach ($this->getUser()->getFollowers($offset, $count) as $follower) {
|
||||||
|
$followers[$i] = $follower->getId();
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach ($this->getUser()->getRequests($offset, $count) as $follower) {
|
||||||
|
$followers[$i] = $follower->getId();
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$response = $usersApi->get(implode(',', $followers), $fields, 0, $count);
|
$response = $followers;
|
||||||
|
$usersApi = new Users($this->getUser());
|
||||||
|
|
||||||
foreach($response as $user)
|
$response = $usersApi->get(implode(',', $followers), $fields, 0, $count);
|
||||||
$user->user_id = $user->id;
|
|
||||||
|
|
||||||
return (object) [
|
foreach ($response as $user) {
|
||||||
"count" => $this->getUser()->getFollowersCount(),
|
$user->user_id = $user->id;
|
||||||
"items" => $response
|
}
|
||||||
];
|
|
||||||
}
|
return (object) [
|
||||||
|
"count" => $this->getUser()->getFollowersCount(),
|
||||||
|
"items" => $response,
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
||||||
use openvk\Web\Models\Repositories\Gifts as GiftsRepo;
|
use openvk\Web\Models\Repositories\Gifts as GiftsRepo;
|
||||||
use openvk\Web\Models\Entities\Notifications\GiftNotification;
|
use openvk\Web\Models\Entities\Notifications\GiftNotification;
|
||||||
|
|
||||||
final class Gifts extends VKAPIRequestHandler
|
final class Gifts extends VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
function get(int $user_id = NULL, int $count = 10, int $offset = 0)
|
public function get(int $user_id = null, int $count = 10, int $offset = 0)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
|
@ -14,94 +18,104 @@ final class Gifts extends VKAPIRequestHandler
|
||||||
$i += $offset;
|
$i += $offset;
|
||||||
$server_url = ovk_scheme(true) . $_SERVER["HTTP_HOST"];
|
$server_url = ovk_scheme(true) . $_SERVER["HTTP_HOST"];
|
||||||
|
|
||||||
if($user_id)
|
if ($user_id) {
|
||||||
$user = (new UsersRepo)->get($user_id);
|
$user = (new UsersRepo())->get($user_id);
|
||||||
else
|
} else {
|
||||||
$user = $this->getUser();
|
$user = $this->getUser();
|
||||||
|
}
|
||||||
|
|
||||||
if(!$user || $user->isDeleted())
|
if (!$user || $user->isDeleted()) {
|
||||||
$this->fail(177, "Invalid user");
|
$this->fail(177, "Invalid user");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$user->canBeViewedBy($this->getUser()))
|
if (!$user->canBeViewedBy($this->getUser())) {
|
||||||
$this->fail(15, "Access denied");
|
$this->fail(15, "Access denied");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if(!$user->getPrivacyPermission('gifts.read', $this->getUser()))
|
if(!$user->getPrivacyPermission('gifts.read', $this->getUser()))
|
||||||
$this->fail(15, "Access denied: this user chose to hide his gifts");*/
|
$this->fail(15, "Access denied: this user chose to hide his gifts");*/
|
||||||
|
|
||||||
|
|
||||||
if(!$user->canBeViewedBy($this->getUser()))
|
if (!$user->canBeViewedBy($this->getUser())) {
|
||||||
$this->fail(15, "Access denied");
|
$this->fail(15, "Access denied");
|
||||||
|
}
|
||||||
|
|
||||||
$gift_item = [];
|
$gift_item = [];
|
||||||
|
|
||||||
$userGifts = array_slice(iterator_to_array($user->getGifts(1, $count, false)), $offset);
|
$userGifts = array_slice(iterator_to_array($user->getGifts(1, $count, false)), $offset);
|
||||||
|
|
||||||
if(sizeof($userGifts) < 0) {
|
if (sizeof($userGifts) < 0) {
|
||||||
return NULL;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($userGifts as $gift) {
|
foreach ($userGifts as $gift) {
|
||||||
if($i < $count) {
|
if ($i < $count) {
|
||||||
$gift_item[] = [
|
$gift_item[] = [
|
||||||
"id" => $i,
|
"id" => $i,
|
||||||
"from_id" => $gift->anon == true ? 0 : $gift->sender->getId(),
|
"from_id" => $gift->anon == true ? 0 : $gift->sender->getId(),
|
||||||
"message" => $gift->caption == NULL ? "" : $gift->caption,
|
"message" => $gift->caption == null ? "" : $gift->caption,
|
||||||
"date" => $gift->sent->timestamp(),
|
"date" => $gift->sent->timestamp(),
|
||||||
"gift" => [
|
"gift" => [
|
||||||
"id" => $gift->gift->getId(),
|
"id" => $gift->gift->getId(),
|
||||||
"thumb_256" => $server_url. $gift->gift->getImage(2),
|
"thumb_256" => $server_url . $gift->gift->getImage(2),
|
||||||
"thumb_96" => $server_url . $gift->gift->getImage(2),
|
"thumb_96" => $server_url . $gift->gift->getImage(2),
|
||||||
"thumb_48" => $server_url . $gift->gift->getImage(2)
|
"thumb_48" => $server_url . $gift->gift->getImage(2),
|
||||||
],
|
],
|
||||||
"privacy" => 0
|
"privacy" => 0,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
$i+=1;
|
$i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $gift_item;
|
return $gift_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
function send(int $user_ids, int $gift_id, string $message = "", int $privacy = 0)
|
public function send(int $user_ids, int $gift_id, string $message = "", int $privacy = 0)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$user = (new UsersRepo)->get((int) $user_ids);
|
$user = (new UsersRepo())->get((int) $user_ids);
|
||||||
|
|
||||||
if(!OPENVK_ROOT_CONF['openvk']['preferences']['commerce'])
|
if (!OPENVK_ROOT_CONF['openvk']['preferences']['commerce']) {
|
||||||
$this->fail(105, "Commerce is disabled on this instance");
|
$this->fail(105, "Commerce is disabled on this instance");
|
||||||
|
}
|
||||||
if(!$user || $user->isDeleted())
|
|
||||||
|
if (!$user || $user->isDeleted()) {
|
||||||
$this->fail(177, "Invalid user");
|
$this->fail(177, "Invalid user");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$user->canBeViewedBy($this->getUser()))
|
if (!$user->canBeViewedBy($this->getUser())) {
|
||||||
$this->fail(15, "Access denied");
|
$this->fail(15, "Access denied");
|
||||||
|
}
|
||||||
|
|
||||||
$gift = (new GiftsRepo)->get($gift_id);
|
$gift = (new GiftsRepo())->get($gift_id);
|
||||||
|
|
||||||
if(!$gift)
|
if (!$gift) {
|
||||||
$this->fail(165, "Invalid gift");
|
$this->fail(165, "Invalid gift");
|
||||||
|
}
|
||||||
|
|
||||||
$price = $gift->getPrice();
|
$price = $gift->getPrice();
|
||||||
$coinsLeft = $this->getUser()->getCoins() - $price;
|
$coinsLeft = $this->getUser()->getCoins() - $price;
|
||||||
|
|
||||||
if(!$gift->canUse($this->getUser()))
|
if (!$gift->canUse($this->getUser())) {
|
||||||
return (object)
|
return (object)
|
||||||
[
|
[
|
||||||
"success" => 0,
|
"success" => 0,
|
||||||
"user_ids" => $user_ids,
|
"user_ids" => $user_ids,
|
||||||
"error" => "You don't have any more of these gifts."
|
"error" => "You don't have any more of these gifts.",
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
if($coinsLeft < 0)
|
if ($coinsLeft < 0) {
|
||||||
return (object)
|
return (object)
|
||||||
[
|
[
|
||||||
"success" => 0,
|
"success" => 0,
|
||||||
"user_ids" => $user_ids,
|
"user_ids" => $user_ids,
|
||||||
"error" => "You don't have enough voices."
|
"error" => "You don't have enough voices.",
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
$user->gift($this->getUser(), $gift, $message);
|
$user->gift($this->getUser(), $gift, $message);
|
||||||
$gift->used();
|
$gift->used();
|
||||||
|
@ -116,11 +130,11 @@ final class Gifts extends VKAPIRequestHandler
|
||||||
[
|
[
|
||||||
"success" => 1,
|
"success" => 1,
|
||||||
"user_ids" => $user_ids,
|
"user_ids" => $user_ids,
|
||||||
"withdraw_votes" => $price
|
"withdraw_votes" => $price,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete()
|
public function delete()
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
@ -129,27 +143,28 @@ final class Gifts extends VKAPIRequestHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
# в vk кстати называется gifts.getCatalog
|
# в vk кстати называется gifts.getCatalog
|
||||||
function getCategories(bool $extended = false, int $page = 1)
|
public function getCategories(bool $extended = false, int $page = 1)
|
||||||
{
|
{
|
||||||
$cats = (new GiftsRepo)->getCategories($page);
|
$cats = (new GiftsRepo())->getCategories($page);
|
||||||
$categ = [];
|
$categ = [];
|
||||||
$i = 0;
|
$i = 0;
|
||||||
$server_url = ovk_scheme(true) . $_SERVER["HTTP_HOST"];
|
$server_url = ovk_scheme(true) . $_SERVER["HTTP_HOST"];
|
||||||
|
|
||||||
if(!OPENVK_ROOT_CONF['openvk']['preferences']['commerce'])
|
if (!OPENVK_ROOT_CONF['openvk']['preferences']['commerce']) {
|
||||||
$this->fail(105, "Commerce is disabled on this instance");
|
$this->fail(105, "Commerce is disabled on this instance");
|
||||||
|
}
|
||||||
|
|
||||||
foreach($cats as $cat) {
|
foreach ($cats as $cat) {
|
||||||
$categ[$i] = [
|
$categ[$i] = [
|
||||||
"name" => $cat->getName(),
|
"name" => $cat->getName(),
|
||||||
"description" => $cat->getDescription(),
|
"description" => $cat->getDescription(),
|
||||||
"id" => $cat->getId(),
|
"id" => $cat->getId(),
|
||||||
"thumbnail" => $server_url . $cat->getThumbnailURL(),
|
"thumbnail" => $server_url . $cat->getThumbnailURL(),
|
||||||
];
|
];
|
||||||
|
|
||||||
if($extended == true) {
|
if ($extended == true) {
|
||||||
$categ[$i]["localizations"] = [];
|
$categ[$i]["localizations"] = [];
|
||||||
foreach(getLanguages() as $lang) {
|
foreach (getLanguages() as $lang) {
|
||||||
$code = $lang["code"];
|
$code = $lang["code"];
|
||||||
$categ[$i]["localizations"][$code] =
|
$categ[$i]["localizations"][$code] =
|
||||||
[
|
[
|
||||||
|
@ -160,30 +175,32 @@ final class Gifts extends VKAPIRequestHandler
|
||||||
}
|
}
|
||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $categ;
|
return $categ;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGiftsInCategory(int $id, int $page = 1)
|
public function getGiftsInCategory(int $id, int $page = 1)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
if(!OPENVK_ROOT_CONF['openvk']['preferences']['commerce'])
|
if (!OPENVK_ROOT_CONF['openvk']['preferences']['commerce']) {
|
||||||
$this->fail(105, "Commerce is disabled on this instance");
|
$this->fail(105, "Commerce is disabled on this instance");
|
||||||
|
}
|
||||||
|
|
||||||
if(!(new GiftsRepo)->getCat($id))
|
if (!(new GiftsRepo())->getCat($id)) {
|
||||||
$this->fail(177, "Category not found");
|
$this->fail(177, "Category not found");
|
||||||
|
}
|
||||||
|
|
||||||
$giftz = ((new GiftsRepo)->getCat($id))->getGifts($page);
|
$giftz = ((new GiftsRepo())->getCat($id))->getGifts($page);
|
||||||
$gifts = [];
|
$gifts = [];
|
||||||
|
|
||||||
foreach($giftz as $gift) {
|
foreach ($giftz as $gift) {
|
||||||
$gifts[] = [
|
$gifts[] = [
|
||||||
"name" => $gift->getName(),
|
"name" => $gift->getName(),
|
||||||
"image" => $gift->getImage(2),
|
"image" => $gift->getImage(2),
|
||||||
"usages_left" => (int)$gift->getUsagesLeft($this->getUser()),
|
"usages_left" => (int) $gift->getUsagesLeft($this->getUser()),
|
||||||
"price" => $gift->getPrice(),
|
"price" => $gift->getPrice(),
|
||||||
"is_free" => $gift->isFree()
|
"is_free" => $gift->isFree(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use openvk\Web\Models\Repositories\Clubs as ClubsRepo;
|
use openvk\Web\Models\Repositories\Clubs as ClubsRepo;
|
||||||
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
||||||
use openvk\Web\Models\Repositories\Posts as PostsRepo;
|
use openvk\Web\Models\Repositories\Posts as PostsRepo;
|
||||||
|
@ -7,46 +11,51 @@ use openvk\Web\Models\Entities\Club;
|
||||||
|
|
||||||
final class Groups extends VKAPIRequestHandler
|
final class Groups extends VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
function get(int $user_id = 0, string $fields = "", int $offset = 0, int $count = 6, bool $online = false, string $filter = "groups"): object
|
public function get(int $user_id = 0, string $fields = "", int $offset = 0, int $count = 6, bool $online = false, string $filter = "groups"): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
# InfoApp fix
|
# InfoApp fix
|
||||||
if($filter == "admin" && ($user_id != 0 && $user_id != $this->getUser()->getId())) {
|
if ($filter == "admin" && ($user_id != 0 && $user_id != $this->getUser()->getId())) {
|
||||||
$this->fail(15, 'Access denied: filter admin is available only for current user');
|
$this->fail(15, 'Access denied: filter admin is available only for current user');
|
||||||
}
|
}
|
||||||
|
|
||||||
$clbs = [];
|
$clbs = [];
|
||||||
if($user_id == 0) {
|
if ($user_id == 0) {
|
||||||
foreach($this->getUser()->getClubs($offset, $filter == "admin", $count, true) as $club)
|
foreach ($this->getUser()->getClubs($offset, $filter == "admin", $count, true) as $club) {
|
||||||
$clbs[] = $club;
|
$clbs[] = $club;
|
||||||
$clbsCount = $this->getUser()->getClubCount();
|
}
|
||||||
|
$clbsCount = $this->getUser()->getClubCount();
|
||||||
} else {
|
} else {
|
||||||
$users = new UsersRepo;
|
$users = new UsersRepo();
|
||||||
$user = $users->get($user_id);
|
$user = $users->get($user_id);
|
||||||
|
|
||||||
if(is_null($user) || $user->isDeleted())
|
if (is_null($user) || $user->isDeleted()) {
|
||||||
$this->fail(15, "Access denied");
|
$this->fail(15, "Access denied");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$user->getPrivacyPermission('groups.read', $this->getUser()))
|
if (!$user->getPrivacyPermission('groups.read', $this->getUser())) {
|
||||||
$this->fail(15, "Access denied: this user chose to hide his groups.");
|
$this->fail(15, "Access denied: this user chose to hide his groups.");
|
||||||
|
}
|
||||||
foreach($user->getClubs($offset, $filter == "admin", $count, true) as $club)
|
|
||||||
$clbs[] = $club;
|
|
||||||
|
|
||||||
$clbsCount = $user->getClubCount();
|
foreach ($user->getClubs($offset, $filter == "admin", $count, true) as $club) {
|
||||||
|
$clbs[] = $club;
|
||||||
|
}
|
||||||
|
|
||||||
|
$clbsCount = $user->getClubCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
$rClubs;
|
$rClubs;
|
||||||
|
|
||||||
$ic = sizeof($clbs);
|
$ic = sizeof($clbs);
|
||||||
if(sizeof($clbs) > $count)
|
if (sizeof($clbs) > $count) {
|
||||||
$ic = $count;
|
$ic = $count;
|
||||||
|
}
|
||||||
|
|
||||||
if(!empty($clbs)) {
|
if (!empty($clbs)) {
|
||||||
for($i=0; $i < $ic; $i++) {
|
for ($i = 0; $i < $ic; $i++) {
|
||||||
$usr = $clbs[$i];
|
$usr = $clbs[$i];
|
||||||
if(is_null($usr)) {
|
if (is_null($usr)) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$rClubs[$i] = (object) [
|
$rClubs[$i] = (object) [
|
||||||
|
@ -59,8 +68,8 @@ final class Groups extends VKAPIRequestHandler
|
||||||
|
|
||||||
$flds = explode(',', $fields);
|
$flds = explode(',', $fields);
|
||||||
|
|
||||||
foreach($flds as $field) {
|
foreach ($flds as $field) {
|
||||||
switch($field) {
|
switch ($field) {
|
||||||
case "verified":
|
case "verified":
|
||||||
$rClubs[$i]->verified = intval($usr->isVerified());
|
$rClubs[$i]->verified = intval($usr->isVerified());
|
||||||
break;
|
break;
|
||||||
|
@ -98,15 +107,15 @@ final class Groups extends VKAPIRequestHandler
|
||||||
$backgrounds = $usr->getBackDropPictureURLs();
|
$backgrounds = $usr->getBackDropPictureURLs();
|
||||||
$rClubs[$i]->background = $backgrounds;
|
$rClubs[$i]->background = $backgrounds;
|
||||||
break;
|
break;
|
||||||
# unstandard feild
|
# unstandard feild
|
||||||
case "suggested_count":
|
case "suggested_count":
|
||||||
if($usr->getWallType() != 2) {
|
if ($usr->getWallType() != 2) {
|
||||||
$rClubs[$i]->suggested_count = NULL;
|
$rClubs[$i]->suggested_count = null;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$rClubs[$i]->suggested_count = $usr->getSuggestedPostsCount($this->getUser());
|
$rClubs[$i]->suggested_count = $usr->getSuggestedPostsCount($this->getUser());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,58 +126,63 @@ final class Groups extends VKAPIRequestHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
"count" => $clbsCount,
|
"count" => $clbsCount,
|
||||||
"items" => $rClubs
|
"items" => $rClubs,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getById(string $group_ids = "", string $group_id = "", string $fields = "", int $offset = 0, int $count = 500): ?array
|
public function getById(string $group_ids = "", string $group_id = "", string $fields = "", int $offset = 0, int $count = 500): ?array
|
||||||
{
|
{
|
||||||
/* Both offset and count SHOULD be used only in OpenVK code,
|
/* Both offset and count SHOULD be used only in OpenVK code,
|
||||||
not in your app or script, since it's not oficially documented by VK */
|
not in your app or script, since it's not oficially documented by VK */
|
||||||
|
|
||||||
$clubs = new ClubsRepo;
|
$clubs = new ClubsRepo();
|
||||||
|
|
||||||
if(empty($group_ids) && !empty($group_id))
|
if (empty($group_ids) && !empty($group_id)) {
|
||||||
$group_ids = $group_id;
|
$group_ids = $group_id;
|
||||||
|
}
|
||||||
if(empty($group_ids) && empty($group_id))
|
|
||||||
|
if (empty($group_ids) && empty($group_id)) {
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: group_ids is undefined");
|
$this->fail(100, "One of the parameters specified was missing or invalid: group_ids is undefined");
|
||||||
|
}
|
||||||
|
|
||||||
$clbs = explode(',', $group_ids);
|
$clbs = explode(',', $group_ids);
|
||||||
$response = array();
|
$response = [];
|
||||||
|
|
||||||
$ic = sizeof($clbs);
|
$ic = sizeof($clbs);
|
||||||
|
|
||||||
if(sizeof($clbs) > $count)
|
if (sizeof($clbs) > $count) {
|
||||||
$ic = $count;
|
$ic = $count;
|
||||||
|
}
|
||||||
|
|
||||||
$clbs = array_slice($clbs, $offset * $count);
|
$clbs = array_slice($clbs, $offset * $count);
|
||||||
|
|
||||||
|
|
||||||
for($i=0; $i < $ic; $i++) {
|
for ($i = 0; $i < $ic; $i++) {
|
||||||
if($i > 500 || $clbs[$i] == 0)
|
if ($i > 500 || $clbs[$i] == 0) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if($clbs[$i] < 0)
|
if ($clbs[$i] < 0) {
|
||||||
$this->fail(100, "ты ошибся чутка, у айди группы убери минус");
|
$this->fail(100, "ты ошибся чутка, у айди группы убери минус");
|
||||||
|
}
|
||||||
|
|
||||||
$clb = $clubs->get((int) $clbs[$i]);
|
$clb = $clubs->get((int) $clbs[$i]);
|
||||||
if(is_null($clb)) {
|
if (is_null($clb)) {
|
||||||
$response[$i] = (object)[
|
$response[$i] = (object) [
|
||||||
"id" => intval($clbs[$i]),
|
"id" => intval($clbs[$i]),
|
||||||
"name" => "DELETED",
|
"name" => "DELETED",
|
||||||
"screen_name" => "club".intval($clbs[$i]),
|
"screen_name" => "club" . intval($clbs[$i]),
|
||||||
"type" => "group",
|
"type" => "group",
|
||||||
"description" => "This group was deleted or it doesn't exist"
|
"description" => "This group was deleted or it doesn't exist",
|
||||||
];
|
];
|
||||||
} else if($clbs[$i] == NULL) {
|
} elseif ($clbs[$i] == null) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$response[$i] = (object)[
|
$response[$i] = (object) [
|
||||||
"id" => $clb->getId(),
|
"id" => $clb->getId(),
|
||||||
"name" => $clb->getName(),
|
"name" => $clb->getName(),
|
||||||
"screen_name" => $clb->getShortCode() ?? "club".$clb->getId(),
|
"screen_name" => $clb->getShortCode() ?? "club" . $clb->getId(),
|
||||||
"is_closed" => false,
|
"is_closed" => false,
|
||||||
"type" => "group",
|
"type" => "group",
|
||||||
"is_member" => !is_null($this->getUser()) ? (int) $clb->getSubscriptionStatus($this->getUser()) : 0,
|
"is_member" => !is_null($this->getUser()) ? (int) $clb->getSubscriptionStatus($this->getUser()) : 0,
|
||||||
|
@ -177,20 +191,20 @@ final class Groups extends VKAPIRequestHandler
|
||||||
|
|
||||||
$flds = explode(',', $fields);
|
$flds = explode(',', $fields);
|
||||||
|
|
||||||
foreach($flds as $field) {
|
foreach ($flds as $field) {
|
||||||
switch($field) {
|
switch ($field) {
|
||||||
case "verified":
|
case "verified":
|
||||||
$response[$i]->verified = intval($clb->isVerified());
|
$response[$i]->verified = intval($clb->isVerified());
|
||||||
break;
|
break;
|
||||||
case "has_photo":
|
case "has_photo":
|
||||||
$response[$i]->has_photo = is_null($clb->getAvatarPhoto()) ? 0 : 1;
|
$response[$i]->has_photo = is_null($clb->getAvatarPhoto()) ? 0 : 1;
|
||||||
break;
|
break;
|
||||||
case "photo_max_orig":
|
case "photo_max_orig":
|
||||||
$response[$i]->photo_max_orig = $clb->getAvatarURL();
|
$response[$i]->photo_max_orig = $clb->getAvatarURL();
|
||||||
break;
|
break;
|
||||||
case "photo_max":
|
case "photo_max":
|
||||||
$response[$i]->photo_max = $clb->getAvatarURL();
|
$response[$i]->photo_max = $clb->getAvatarURL();
|
||||||
break;
|
break;
|
||||||
case "photo_50":
|
case "photo_50":
|
||||||
$response[$i]->photo_50 = $clb->getAvatarURL();
|
$response[$i]->photo_50 = $clb->getAvatarURL();
|
||||||
break;
|
break;
|
||||||
|
@ -206,14 +220,14 @@ final class Groups extends VKAPIRequestHandler
|
||||||
case "photo_400_orig":
|
case "photo_400_orig":
|
||||||
$response[$i]->photo_400_orig = $clb->getAvatarURL("normal");
|
$response[$i]->photo_400_orig = $clb->getAvatarURL("normal");
|
||||||
break;
|
break;
|
||||||
case "members_count":
|
case "members_count":
|
||||||
$response[$i]->members_count = $clb->getFollowersCount();
|
$response[$i]->members_count = $clb->getFollowersCount();
|
||||||
break;
|
break;
|
||||||
case "site":
|
case "site":
|
||||||
$response[$i]->site = $clb->getWebsite();
|
$response[$i]->site = $clb->getWebsite();
|
||||||
break;
|
break;
|
||||||
case "description":
|
case "description":
|
||||||
$response[$i]->description = $clb->getDescription();
|
$response[$i]->description = $clb->getDescription();
|
||||||
break;
|
break;
|
||||||
case "can_suggest":
|
case "can_suggest":
|
||||||
$response[$i]->can_suggest = !$clb->canBeModifiedBy($this->getUser()) && $clb->getWallType() == 2;
|
$response[$i]->can_suggest = !$clb->canBeModifiedBy($this->getUser()) && $clb->getWallType() == 2;
|
||||||
|
@ -222,10 +236,10 @@ final class Groups extends VKAPIRequestHandler
|
||||||
$backgrounds = $clb->getBackDropPictureURLs();
|
$backgrounds = $clb->getBackDropPictureURLs();
|
||||||
$response[$i]->background = $backgrounds;
|
$response[$i]->background = $backgrounds;
|
||||||
break;
|
break;
|
||||||
# unstandard feild
|
# unstandard feild
|
||||||
case "suggested_count":
|
case "suggested_count":
|
||||||
if($clb->getWallType() != 2) {
|
if ($clb->getWallType() != 2) {
|
||||||
$response[$i]->suggested_count = NULL;
|
$response[$i]->suggested_count = null;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,20 +249,23 @@ final class Groups extends VKAPIRequestHandler
|
||||||
$contacts;
|
$contacts;
|
||||||
$contactTmp = $clb->getManagers(1, true);
|
$contactTmp = $clb->getManagers(1, true);
|
||||||
|
|
||||||
foreach($contactTmp as $contact)
|
foreach ($contactTmp as $contact) {
|
||||||
$contacts[] = array(
|
$contacts[] = [
|
||||||
"user_id" => $contact->getUser()->getId(),
|
"user_id" => $contact->getUser()->getId(),
|
||||||
"desc" => $contact->getComment()
|
"desc" => $contact->getComment(),
|
||||||
);
|
];
|
||||||
|
}
|
||||||
|
|
||||||
$response[$i]->contacts = $contacts;
|
$response[$i]->contacts = $contacts;
|
||||||
break;
|
break;
|
||||||
case "can_post":
|
case "can_post":
|
||||||
if(!is_null($this->getUser()))
|
if (!is_null($this->getUser())) {
|
||||||
if($clb->canBeModifiedBy($this->getUser()))
|
if ($clb->canBeModifiedBy($this->getUser())) {
|
||||||
$response[$i]->can_post = true;
|
$response[$i]->can_post = true;
|
||||||
else
|
} else {
|
||||||
$response[$i]->can_post = $clb->canPost();
|
$response[$i]->can_post = $clb->canPost();
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,21 +275,22 @@ final class Groups extends VKAPIRequestHandler
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
function search(string $q, int $offset = 0, int $count = 100, string $fields = "screen_name,is_admin,is_member,is_advertiser,photo_50,photo_100,photo_200")
|
public function search(string $q, int $offset = 0, int $count = 100, string $fields = "screen_name,is_admin,is_member,is_advertiser,photo_50,photo_100,photo_200")
|
||||||
{
|
{
|
||||||
if($count > 100) {
|
if ($count > 100) {
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: count should be less or equal to 100");
|
$this->fail(100, "One of the parameters specified was missing or invalid: count should be less or equal to 100");
|
||||||
}
|
}
|
||||||
|
|
||||||
$clubs = new ClubsRepo;
|
$clubs = new ClubsRepo();
|
||||||
|
|
||||||
$array = [];
|
|
||||||
$find = $clubs->find($q);
|
|
||||||
|
|
||||||
foreach ($find->offsetLimit($offset, $count) as $group)
|
$array = [];
|
||||||
|
$find = $clubs->find($q);
|
||||||
|
|
||||||
|
foreach ($find->offsetLimit($offset, $count) as $group) {
|
||||||
$array[] = $group->getId();
|
$array[] = $group->getId();
|
||||||
|
}
|
||||||
if(!$array || sizeof($array) < 1) {
|
|
||||||
|
if (!$array || sizeof($array) < 1) {
|
||||||
return (object) [
|
return (object) [
|
||||||
"count" => 0,
|
"count" => 0,
|
||||||
"items" => [],
|
"items" => [],
|
||||||
|
@ -280,47 +298,49 @@ final class Groups extends VKAPIRequestHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
"count" => $find->size(),
|
"count" => $find->size(),
|
||||||
"items" => $this->getById(implode(',', $array), "", $fields)
|
"items" => $this->getById(implode(',', $array), "", $fields),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function join(int $group_id)
|
public function join(int $group_id)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$club = (new ClubsRepo)->get($group_id);
|
$club = (new ClubsRepo())->get($group_id);
|
||||||
|
|
||||||
$isMember = !is_null($this->getUser()) ? (int) $club->getSubscriptionStatus($this->getUser()) : 0;
|
$isMember = !is_null($this->getUser()) ? (int) $club->getSubscriptionStatus($this->getUser()) : 0;
|
||||||
|
|
||||||
if($isMember == 0)
|
if ($isMember == 0) {
|
||||||
$club->toggleSubscription($this->getUser());
|
$club->toggleSubscription($this->getUser());
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function leave(int $group_id)
|
public function leave(int $group_id)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$club = (new ClubsRepo)->get($group_id);
|
$club = (new ClubsRepo())->get($group_id);
|
||||||
|
|
||||||
$isMember = !is_null($this->getUser()) ? (int) $club->getSubscriptionStatus($this->getUser()) : 0;
|
$isMember = !is_null($this->getUser()) ? (int) $club->getSubscriptionStatus($this->getUser()) : 0;
|
||||||
|
|
||||||
if($isMember == 1)
|
if ($isMember == 1) {
|
||||||
$club->toggleSubscription($this->getUser());
|
$club->toggleSubscription($this->getUser());
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function create(string $title, string $description = "", string $type = "group", int $public_category = 1, int $public_subcategory = 1, int $subtype = 1)
|
public function create(string $title, string $description = "", string $type = "group", int $public_category = 1, int $public_subcategory = 1, int $subtype = 1)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$club = new Club;
|
$club = new Club();
|
||||||
|
|
||||||
$club->setName($title);
|
$club->setName($title);
|
||||||
$club->setAbout($description);
|
$club->setAbout($description);
|
||||||
|
@ -329,73 +349,80 @@ final class Groups extends VKAPIRequestHandler
|
||||||
|
|
||||||
$club->toggleSubscription($this->getUser());
|
$club->toggleSubscription($this->getUser());
|
||||||
|
|
||||||
return $this->getById((string)$club->getId());
|
return $this->getById((string) $club->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
function edit(
|
public function edit(
|
||||||
int $group_id,
|
int $group_id,
|
||||||
string $title = NULL,
|
string $title = null,
|
||||||
string $description = NULL,
|
string $description = null,
|
||||||
string $screen_name = NULL,
|
string $screen_name = null,
|
||||||
string $website = NULL,
|
string $website = null,
|
||||||
int $wall = -1,
|
int $wall = -1,
|
||||||
int $topics = NULL,
|
int $topics = null,
|
||||||
int $adminlist = NULL,
|
int $adminlist = null,
|
||||||
int $topicsAboveWall = NULL,
|
int $topicsAboveWall = null,
|
||||||
int $hideFromGlobalFeed = NULL,
|
int $hideFromGlobalFeed = null,
|
||||||
int $audio = NULL)
|
int $audio = null
|
||||||
{
|
) {
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$club = (new ClubsRepo)->get($group_id);
|
$club = (new ClubsRepo())->get($group_id);
|
||||||
|
|
||||||
if(!$club) $this->fail(203, "Club not found");
|
if (!$club) {
|
||||||
if(!$club || !$club->canBeModifiedBy($this->getUser())) $this->fail(15, "You can't modify this group.");
|
$this->fail(203, "Club not found");
|
||||||
if(!empty($screen_name) && !$club->setShortcode($screen_name)) $this->fail(103, "Invalid shortcode.");
|
}
|
||||||
|
if (!$club || !$club->canBeModifiedBy($this->getUser())) {
|
||||||
|
$this->fail(15, "You can't modify this group.");
|
||||||
|
}
|
||||||
|
if (!empty($screen_name) && !$club->setShortcode($screen_name)) {
|
||||||
|
$this->fail(103, "Invalid shortcode.");
|
||||||
|
}
|
||||||
|
|
||||||
|
!empty($title) ? $club->setName($title) : null;
|
||||||
|
!empty($description) ? $club->setAbout($description) : null;
|
||||||
|
!empty($screen_name) ? $club->setShortcode($screen_name) : null;
|
||||||
|
!empty($website) ? $club->setWebsite((!parse_url($website, PHP_URL_SCHEME) ? "https://" : "") . $website) : null;
|
||||||
|
|
||||||
!empty($title) ? $club->setName($title) : NULL;
|
|
||||||
!empty($description) ? $club->setAbout($description) : NULL;
|
|
||||||
!empty($screen_name) ? $club->setShortcode($screen_name) : NULL;
|
|
||||||
!empty($website) ? $club->setWebsite((!parse_url($website, PHP_URL_SCHEME) ? "https://" : "") . $website) : NULL;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$wall != -1 ? $club->setWall($wall) : NULL;
|
$wall != -1 ? $club->setWall($wall) : null;
|
||||||
} catch(\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->fail(50, "Invalid wall value");
|
$this->fail(50, "Invalid wall value");
|
||||||
}
|
}
|
||||||
|
|
||||||
!empty($topics) ? $club->setEveryone_Can_Create_Topics($topics) : NULL;
|
!empty($topics) ? $club->setEveryone_Can_Create_Topics($topics) : null;
|
||||||
!empty($adminlist) ? $club->setAdministrators_List_Display($adminlist) : NULL;
|
!empty($adminlist) ? $club->setAdministrators_List_Display($adminlist) : null;
|
||||||
!empty($topicsAboveWall) ? $club->setDisplay_Topics_Above_Wall($topicsAboveWall) : NULL;
|
!empty($topicsAboveWall) ? $club->setDisplay_Topics_Above_Wall($topicsAboveWall) : null;
|
||||||
|
|
||||||
if (!$club->isHidingFromGlobalFeedEnforced()) {
|
if (!$club->isHidingFromGlobalFeedEnforced()) {
|
||||||
!empty($hideFromGlobalFeed) ? $club->setHide_From_Global_Feed($hideFromGlobalFeed) : NULL;
|
!empty($hideFromGlobalFeed) ? $club->setHide_From_Global_Feed($hideFromGlobalFeed) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
in_array($audio, [0, 1]) ? $club->setEveryone_can_upload_audios($audio) : NULL;
|
in_array($audio, [0, 1]) ? $club->setEveryone_can_upload_audios($audio) : null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$club->save();
|
$club->save();
|
||||||
} catch(\TypeError $e) {
|
} catch (\TypeError $e) {
|
||||||
$this->fail(15, "Nothing changed");
|
$this->fail(15, "Nothing changed");
|
||||||
} catch(\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->fail(18, "An unknown error occurred: maybe you set an incorrect value?");
|
$this->fail(18, "An unknown error occurred: maybe you set an incorrect value?");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMembers(string $group_id, string $sort = "id_asc", int $offset = 0, int $count = 100, string $fields = "", string $filter = "any")
|
public function getMembers(string $group_id, string $sort = "id_asc", int $offset = 0, int $count = 100, string $fields = "", string $filter = "any")
|
||||||
{
|
{
|
||||||
# bdate,can_post,can_see_all_posts,can_see_audio,can_write_private_message,city,common_count,connections,contacts,country,domain,education,has_mobile,last_seen,lists,online,online_mobile,photo_100,photo_200,photo_200_orig,photo_400_orig,photo_50,photo_max,photo_max_orig,relation,relatives,schools,sex,site,status,universities
|
# bdate,can_post,can_see_all_posts,can_see_audio,can_write_private_message,city,common_count,connections,contacts,country,domain,education,has_mobile,last_seen,lists,online,online_mobile,photo_100,photo_200,photo_200_orig,photo_400_orig,photo_50,photo_max,photo_max_orig,relation,relatives,schools,sex,site,status,universities
|
||||||
$club = (new ClubsRepo)->get((int) $group_id);
|
$club = (new ClubsRepo())->get((int) $group_id);
|
||||||
if(!$club)
|
if (!$club) {
|
||||||
$this->fail(125, "Invalid group id");
|
$this->fail(125, "Invalid group id");
|
||||||
|
}
|
||||||
|
|
||||||
$sorter = "follower ASC";
|
$sorter = "follower ASC";
|
||||||
|
|
||||||
switch($sort) {
|
switch ($sort) {
|
||||||
default:
|
default:
|
||||||
case "time_asc":
|
case "time_asc":
|
||||||
case "id_asc":
|
case "id_asc":
|
||||||
|
@ -409,14 +436,14 @@ final class Groups extends VKAPIRequestHandler
|
||||||
|
|
||||||
$members = array_slice(iterator_to_array($club->getFollowers(1, $count, $sorter)), $offset);
|
$members = array_slice(iterator_to_array($club->getFollowers(1, $count, $sorter)), $offset);
|
||||||
$arr = (object) [
|
$arr = (object) [
|
||||||
"count" => count($members),
|
"count" => count($members),
|
||||||
"items" => array()];
|
"items" => []];
|
||||||
|
|
||||||
$filds = explode(",", $fields);
|
$filds = explode(",", $fields);
|
||||||
|
|
||||||
$i = 0;
|
$i = 0;
|
||||||
foreach($members as $member) {
|
foreach ($members as $member) {
|
||||||
if($i > $count) {
|
if ($i > $count) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,16 +453,16 @@ final class Groups extends VKAPIRequestHandler
|
||||||
"last_name" => $member->getLastName(),
|
"last_name" => $member->getLastName(),
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach($filds as $fild) {
|
foreach ($filds as $fild) {
|
||||||
$canView = $member->canBeViewedBy($this->getUser());
|
$canView = $member->canBeViewedBy($this->getUser());
|
||||||
switch($fild) {
|
switch ($fild) {
|
||||||
case "bdate":
|
case "bdate":
|
||||||
if(!$canView) {
|
if (!$canView) {
|
||||||
$arr->items[$i]->bdate = "01.01.1970";
|
$arr->items[$i]->bdate = "01.01.1970";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$arr->items[$i]->bdate = $member->getBirthday() ? $member->getBirthday()->format('%e.%m.%Y') : NULL;
|
$arr->items[$i]->bdate = $member->getBirthday() ? $member->getBirthday()->format('%e.%m.%Y') : null;
|
||||||
break;
|
break;
|
||||||
case "can_post":
|
case "can_post":
|
||||||
$arr->items[$i]->can_post = $club->canBeModifiedBy($member);
|
$arr->items[$i]->can_post = $club->canBeModifiedBy($member);
|
||||||
|
@ -456,7 +483,7 @@ final class Groups extends VKAPIRequestHandler
|
||||||
$arr->items[$i]->connections = 1;
|
$arr->items[$i]->connections = 1;
|
||||||
break;
|
break;
|
||||||
case "contacts":
|
case "contacts":
|
||||||
if(!$canView) {
|
if (!$canView) {
|
||||||
$arr->items[$i]->contacts = "secret@gmail.com";
|
$arr->items[$i]->contacts = "secret@gmail.com";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -476,7 +503,7 @@ final class Groups extends VKAPIRequestHandler
|
||||||
$arr->items[$i]->has_mobile = false;
|
$arr->items[$i]->has_mobile = false;
|
||||||
break;
|
break;
|
||||||
case "last_seen":
|
case "last_seen":
|
||||||
if(!$canView) {
|
if (!$canView) {
|
||||||
$arr->items[$i]->last_seen = 0;
|
$arr->items[$i]->last_seen = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -487,7 +514,7 @@ final class Groups extends VKAPIRequestHandler
|
||||||
$arr->items[$i]->lists = "";
|
$arr->items[$i]->lists = "";
|
||||||
break;
|
break;
|
||||||
case "online":
|
case "online":
|
||||||
if(!$canView) {
|
if (!$canView) {
|
||||||
$arr->items[$i]->online = false;
|
$arr->items[$i]->online = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -495,7 +522,7 @@ final class Groups extends VKAPIRequestHandler
|
||||||
$arr->items[$i]->online = $member->isOnline();
|
$arr->items[$i]->online = $member->isOnline();
|
||||||
break;
|
break;
|
||||||
case "online_mobile":
|
case "online_mobile":
|
||||||
if(!$canView) {
|
if (!$canView) {
|
||||||
$arr->items[$i]->online_mobile = false;
|
$arr->items[$i]->online_mobile = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -530,7 +557,7 @@ final class Groups extends VKAPIRequestHandler
|
||||||
$arr->items[$i]->schools = 0;
|
$arr->items[$i]->schools = 0;
|
||||||
break;
|
break;
|
||||||
case "sex":
|
case "sex":
|
||||||
if(!$canView) {
|
if (!$canView) {
|
||||||
$arr->items[$i]->sex = -1;
|
$arr->items[$i]->sex = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -538,15 +565,15 @@ final class Groups extends VKAPIRequestHandler
|
||||||
$arr->items[$i]->sex = $member->isFemale() ? 1 : 2;
|
$arr->items[$i]->sex = $member->isFemale() ? 1 : 2;
|
||||||
break;
|
break;
|
||||||
case "site":
|
case "site":
|
||||||
if(!$canView) {
|
if (!$canView) {
|
||||||
$arr->items[$i]->site = NULL;
|
$arr->items[$i]->site = null;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$arr->items[$i]->site = $member->getWebsite();
|
$arr->items[$i]->site = $member->getWebsite();
|
||||||
break;
|
break;
|
||||||
case "status":
|
case "status":
|
||||||
if(!$canView) {
|
if (!$canView) {
|
||||||
$arr->items[$i]->status = "r";
|
$arr->items[$i]->status = "r";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -563,17 +590,18 @@ final class Groups extends VKAPIRequestHandler
|
||||||
return $arr;
|
return $arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSettings(string $group_id)
|
public function getSettings(string $group_id)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$club = (new ClubsRepo)->get((int)$group_id);
|
$club = (new ClubsRepo())->get((int) $group_id);
|
||||||
|
|
||||||
if(!$club || !$club->canBeModifiedBy($this->getUser()))
|
if (!$club || !$club->canBeModifiedBy($this->getUser())) {
|
||||||
$this->fail(15, "You can't get settings of this group.");
|
$this->fail(15, "You can't get settings of this group.");
|
||||||
|
}
|
||||||
|
|
||||||
$arr = (object) [
|
$arr = (object) [
|
||||||
"title" => $club->getName(),
|
"title" => $club->getName(),
|
||||||
"description" => $club->getDescription() != NULL ? $club->getDescription() : "",
|
"description" => $club->getDescription() != null ? $club->getDescription() : "",
|
||||||
"address" => $club->getShortcode(),
|
"address" => $club->getShortcode(),
|
||||||
"wall" => $club->getWallType(), # отличается от вкшных но да ладно
|
"wall" => $club->getWallType(), # отличается от вкшных но да ладно
|
||||||
"photos" => 1,
|
"photos" => 1,
|
||||||
|
@ -589,13 +617,13 @@ final class Groups extends VKAPIRequestHandler
|
||||||
"access" => 1,
|
"access" => 1,
|
||||||
"subject" => 1,
|
"subject" => 1,
|
||||||
"subject_list" => [
|
"subject_list" => [
|
||||||
0 => "в",
|
0 => "в",
|
||||||
1 => "опенвк",
|
1 => "опенвк",
|
||||||
2 => "нет",
|
2 => "нет",
|
||||||
3 => "категорий",
|
3 => "категорий",
|
||||||
4 => "групп",
|
4 => "групп",
|
||||||
],
|
],
|
||||||
"rss" => "/club".$club->getId()."/rss",
|
"rss" => "/club" . $club->getId() . "/rss",
|
||||||
"website" => $club->getWebsite(),
|
"website" => $club->getWebsite(),
|
||||||
"age_limits" => 0,
|
"age_limits" => 0,
|
||||||
"market" => [],
|
"market" => [],
|
||||||
|
@ -604,24 +632,27 @@ final class Groups extends VKAPIRequestHandler
|
||||||
return $arr;
|
return $arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isMember(string $group_id, int $user_id, string $user_ids = "", bool $extended = false)
|
public function isMember(string $group_id, int $user_id, string $user_ids = "", bool $extended = false)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$id = $user_id != NULL ? $user_id : explode(",", $user_ids);
|
$id = $user_id != null ? $user_id : explode(",", $user_ids);
|
||||||
|
|
||||||
if($group_id < 0)
|
if ($group_id < 0) {
|
||||||
$this->fail(228, "Remove the minus from group_id");
|
$this->fail(228, "Remove the minus from group_id");
|
||||||
|
}
|
||||||
|
|
||||||
$club = (new ClubsRepo)->get((int)$group_id);
|
$club = (new ClubsRepo())->get((int) $group_id);
|
||||||
$usver = (new UsersRepo)->get((int)$id);
|
$usver = (new UsersRepo())->get((int) $id);
|
||||||
|
|
||||||
if(!$club || $group_id == 0)
|
if (!$club || $group_id == 0) {
|
||||||
$this->fail(203, "Invalid club");
|
$this->fail(203, "Invalid club");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$usver || $usver->isDeleted() || $user_id == 0)
|
if (!$usver || $usver->isDeleted() || $user_id == 0) {
|
||||||
$this->fail(30, "Invalid user");
|
$this->fail(30, "Invalid user");
|
||||||
|
}
|
||||||
|
|
||||||
if($extended == false) {
|
if ($extended == false) {
|
||||||
return $club->getSubscriptionStatus($usver) ? 1 : 0;
|
return $club->getSubscriptionStatus($usver) ? 1 : 0;
|
||||||
} else {
|
} else {
|
||||||
return (object)
|
return (object)
|
||||||
|
@ -630,12 +661,12 @@ final class Groups extends VKAPIRequestHandler
|
||||||
"request" => 0,
|
"request" => 0,
|
||||||
"invitation" => 0,
|
"invitation" => 0,
|
||||||
"can_invite" => 0,
|
"can_invite" => 0,
|
||||||
"can_recall" => 0
|
"can_recall" => 0,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function remove(int $group_id, int $user_id)
|
public function remove(int $group_id, int $user_id)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
|
|
|
@ -1,206 +1,217 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
namespace openvk\VKAPI\Handlers;
|
|
||||||
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
declare(strict_types=1);
|
||||||
use openvk\Web\Models\Repositories\Posts as PostsRepo;
|
|
||||||
use openvk\Web\Models\Repositories\Comments as CommentsRepo;
|
namespace openvk\VKAPI\Handlers;
|
||||||
use openvk\Web\Models\Repositories\Videos as VideosRepo;
|
|
||||||
use openvk\Web\Models\Repositories\Photos as PhotosRepo;
|
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
||||||
use openvk\Web\Models\Repositories\Notes as NotesRepo;
|
use openvk\Web\Models\Repositories\Posts as PostsRepo;
|
||||||
|
use openvk\Web\Models\Repositories\Comments as CommentsRepo;
|
||||||
|
use openvk\Web\Models\Repositories\Videos as VideosRepo;
|
||||||
final class Likes extends VKAPIRequestHandler
|
use openvk\Web\Models\Repositories\Photos as PhotosRepo;
|
||||||
{
|
use openvk\Web\Models\Repositories\Notes as NotesRepo;
|
||||||
function add(string $type, int $owner_id, int $item_id): object
|
|
||||||
{
|
final class Likes extends VKAPIRequestHandler
|
||||||
$this->requireUser();
|
{
|
||||||
$this->willExecuteWriteAction();
|
public function add(string $type, int $owner_id, int $item_id): object
|
||||||
|
{
|
||||||
$postable = NULL;
|
$this->requireUser();
|
||||||
switch($type) {
|
$this->willExecuteWriteAction();
|
||||||
case "post":
|
|
||||||
$post = (new PostsRepo)->getPostById($owner_id, $item_id);
|
$postable = null;
|
||||||
$postable = $post;
|
switch ($type) {
|
||||||
break;
|
case "post":
|
||||||
case "comment":
|
$post = (new PostsRepo())->getPostById($owner_id, $item_id);
|
||||||
$comment = (new CommentsRepo)->get($item_id);
|
$postable = $post;
|
||||||
$postable = $comment;
|
break;
|
||||||
break;
|
case "comment":
|
||||||
case "video":
|
$comment = (new CommentsRepo())->get($item_id);
|
||||||
$video = (new VideosRepo)->getByOwnerAndVID($owner_id, $item_id);
|
$postable = $comment;
|
||||||
$postable = $video;
|
break;
|
||||||
break;
|
case "video":
|
||||||
case "photo":
|
$video = (new VideosRepo())->getByOwnerAndVID($owner_id, $item_id);
|
||||||
$photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $item_id);
|
$postable = $video;
|
||||||
$postable = $photo;
|
break;
|
||||||
break;
|
case "photo":
|
||||||
case "note":
|
$photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $item_id);
|
||||||
$note = (new NotesRepo)->getNoteById($owner_id, $item_id);
|
$postable = $photo;
|
||||||
$postable = $note;
|
break;
|
||||||
break;
|
case "note":
|
||||||
default:
|
$note = (new NotesRepo())->getNoteById($owner_id, $item_id);
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: incorrect type");
|
$postable = $note;
|
||||||
}
|
break;
|
||||||
|
default:
|
||||||
if(is_null($postable) || $postable->isDeleted())
|
$this->fail(100, "One of the parameters specified was missing or invalid: incorrect type");
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: object not found");
|
}
|
||||||
|
|
||||||
if(!$postable->canBeViewedBy($this->getUser() ?? NULL)) {
|
if (is_null($postable) || $postable->isDeleted()) {
|
||||||
$this->fail(2, "Access to postable denied");
|
$this->fail(100, "One of the parameters specified was missing or invalid: object not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
$postable->setLike(true, $this->getUser());
|
if (!$postable->canBeViewedBy($this->getUser() ?? null)) {
|
||||||
|
$this->fail(2, "Access to postable denied");
|
||||||
return (object) [
|
}
|
||||||
"likes" => $postable->getLikesCount()
|
|
||||||
];
|
$postable->setLike(true, $this->getUser());
|
||||||
}
|
|
||||||
|
return (object) [
|
||||||
function delete(string $type, int $owner_id, int $item_id): object
|
"likes" => $postable->getLikesCount(),
|
||||||
{
|
];
|
||||||
$this->requireUser();
|
}
|
||||||
$this->willExecuteWriteAction();
|
|
||||||
|
public function delete(string $type, int $owner_id, int $item_id): object
|
||||||
$postable = NULL;
|
{
|
||||||
switch($type) {
|
$this->requireUser();
|
||||||
case "post":
|
$this->willExecuteWriteAction();
|
||||||
$post = (new PostsRepo)->getPostById($owner_id, $item_id);
|
|
||||||
$postable = $post;
|
$postable = null;
|
||||||
break;
|
switch ($type) {
|
||||||
case "comment":
|
case "post":
|
||||||
$comment = (new CommentsRepo)->get($item_id);
|
$post = (new PostsRepo())->getPostById($owner_id, $item_id);
|
||||||
$postable = $comment;
|
$postable = $post;
|
||||||
break;
|
break;
|
||||||
case "video":
|
case "comment":
|
||||||
$video = (new VideosRepo)->getByOwnerAndVID($owner_id, $item_id);
|
$comment = (new CommentsRepo())->get($item_id);
|
||||||
$postable = $video;
|
$postable = $comment;
|
||||||
break;
|
break;
|
||||||
case "photo":
|
case "video":
|
||||||
$photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $item_id);
|
$video = (new VideosRepo())->getByOwnerAndVID($owner_id, $item_id);
|
||||||
$postable = $photo;
|
$postable = $video;
|
||||||
break;
|
break;
|
||||||
case "note":
|
case "photo":
|
||||||
$note = (new NotesRepo)->getNoteById($owner_id, $item_id);
|
$photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $item_id);
|
||||||
$postable = $note;
|
$postable = $photo;
|
||||||
break;
|
break;
|
||||||
default:
|
case "note":
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: incorrect type");
|
$note = (new NotesRepo())->getNoteById($owner_id, $item_id);
|
||||||
}
|
$postable = $note;
|
||||||
|
break;
|
||||||
if(is_null($postable) || $postable->isDeleted())
|
default:
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: object not found");
|
$this->fail(100, "One of the parameters specified was missing or invalid: incorrect type");
|
||||||
|
}
|
||||||
if(!$postable->canBeViewedBy($this->getUser() ?? NULL)) {
|
|
||||||
$this->fail(2, "Access to postable denied");
|
if (is_null($postable) || $postable->isDeleted()) {
|
||||||
}
|
$this->fail(100, "One of the parameters specified was missing or invalid: object not found");
|
||||||
|
}
|
||||||
if(!is_null($postable)) {
|
|
||||||
$postable->setLike(false, $this->getUser());
|
if (!$postable->canBeViewedBy($this->getUser() ?? null)) {
|
||||||
|
$this->fail(2, "Access to postable denied");
|
||||||
return (object) [
|
}
|
||||||
"likes" => $postable->getLikesCount()
|
|
||||||
];
|
if (!is_null($postable)) {
|
||||||
}
|
$postable->setLike(false, $this->getUser());
|
||||||
}
|
|
||||||
|
return (object) [
|
||||||
function isLiked(int $user_id, string $type, int $owner_id, int $item_id): object
|
"likes" => $postable->getLikesCount(),
|
||||||
{
|
];
|
||||||
$this->requireUser();
|
}
|
||||||
|
}
|
||||||
$user = (new UsersRepo)->get($user_id);
|
|
||||||
|
public function isLiked(int $user_id, string $type, int $owner_id, int $item_id): object
|
||||||
if(is_null($user) || $user->isDeleted())
|
{
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: user not found");
|
$this->requireUser();
|
||||||
|
|
||||||
if(!$user->canBeViewedBy($this->getUser())) {
|
$user = (new UsersRepo())->get($user_id);
|
||||||
$this->fail(1984, "Access denied: you can't see this user");
|
|
||||||
}
|
if (is_null($user) || $user->isDeleted()) {
|
||||||
|
$this->fail(100, "One of the parameters specified was missing or invalid: user not found");
|
||||||
$postable = NULL;
|
}
|
||||||
switch($type) {
|
|
||||||
case "post":
|
if (!$user->canBeViewedBy($this->getUser())) {
|
||||||
$post = (new PostsRepo)->getPostById($owner_id, $item_id);
|
$this->fail(1984, "Access denied: you can't see this user");
|
||||||
$postable = $post;
|
}
|
||||||
break;
|
|
||||||
case "comment":
|
$postable = null;
|
||||||
$comment = (new CommentsRepo)->get($item_id);
|
switch ($type) {
|
||||||
$postable = $comment;
|
case "post":
|
||||||
break;
|
$post = (new PostsRepo())->getPostById($owner_id, $item_id);
|
||||||
case "video":
|
$postable = $post;
|
||||||
$video = (new VideosRepo)->getByOwnerAndVID($owner_id, $item_id);
|
break;
|
||||||
$postable = $video;
|
case "comment":
|
||||||
break;
|
$comment = (new CommentsRepo())->get($item_id);
|
||||||
case "photo":
|
$postable = $comment;
|
||||||
$photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $item_id);
|
break;
|
||||||
$postable = $photo;
|
case "video":
|
||||||
break;
|
$video = (new VideosRepo())->getByOwnerAndVID($owner_id, $item_id);
|
||||||
case "note":
|
$postable = $video;
|
||||||
$note = (new NotesRepo)->getNoteById($owner_id, $item_id);
|
break;
|
||||||
$postable = $note;
|
case "photo":
|
||||||
break;
|
$photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $item_id);
|
||||||
default:
|
$postable = $photo;
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: incorrect type");
|
break;
|
||||||
}
|
case "note":
|
||||||
|
$note = (new NotesRepo())->getNoteById($owner_id, $item_id);
|
||||||
if(is_null($postable) || $postable->isDeleted())
|
$postable = $note;
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: object not found");
|
break;
|
||||||
|
default:
|
||||||
if(!$postable->canBeViewedBy($this->getUser())) {
|
$this->fail(100, "One of the parameters specified was missing or invalid: incorrect type");
|
||||||
$this->fail(665, "Access to postable denied");
|
}
|
||||||
}
|
|
||||||
|
if (is_null($postable) || $postable->isDeleted()) {
|
||||||
return (object) [
|
$this->fail(100, "One of the parameters specified was missing or invalid: object not found");
|
||||||
"liked" => (int) $postable->hasLikeFrom($user),
|
}
|
||||||
"copied" => 0
|
|
||||||
];
|
if (!$postable->canBeViewedBy($this->getUser())) {
|
||||||
}
|
$this->fail(665, "Access to postable denied");
|
||||||
|
}
|
||||||
function getList(string $type, int $owner_id, int $item_id, bool $extended = false, int $offset = 0, int $count = 10, bool $skip_own = false)
|
|
||||||
{
|
return (object) [
|
||||||
$this->requireUser();
|
"liked" => (int) $postable->hasLikeFrom($user),
|
||||||
|
"copied" => 0,
|
||||||
$object = NULL;
|
];
|
||||||
|
}
|
||||||
switch($type) {
|
|
||||||
case "post":
|
public function getList(string $type, int $owner_id, int $item_id, bool $extended = false, int $offset = 0, int $count = 10, bool $skip_own = false)
|
||||||
$object = (new PostsRepo)->getPostById($owner_id, $item_id);
|
{
|
||||||
break;
|
$this->requireUser();
|
||||||
case "comment":
|
|
||||||
$object = (new CommentsRepo)->get($item_id);
|
$object = null;
|
||||||
break;
|
|
||||||
case "photo":
|
switch ($type) {
|
||||||
$object = (new PhotosRepo)->getByOwnerAndVID($owner_id, $item_id);
|
case "post":
|
||||||
break;
|
$object = (new PostsRepo())->getPostById($owner_id, $item_id);
|
||||||
case "video":
|
break;
|
||||||
$object = (new VideosRepo)->getByOwnerAndVID($owner_id, $item_id);
|
case "comment":
|
||||||
break;
|
$object = (new CommentsRepo())->get($item_id);
|
||||||
default:
|
break;
|
||||||
$this->fail(58, "Invalid type");
|
case "photo":
|
||||||
break;
|
$object = (new PhotosRepo())->getByOwnerAndVID($owner_id, $item_id);
|
||||||
}
|
break;
|
||||||
|
case "video":
|
||||||
if(!$object || $object->isDeleted())
|
$object = (new VideosRepo())->getByOwnerAndVID($owner_id, $item_id);
|
||||||
$this->fail(56, "Invalid postable");
|
break;
|
||||||
|
default:
|
||||||
if(!$object->canBeViewedBy($this->getUser()))
|
$this->fail(58, "Invalid type");
|
||||||
$this->fail(665, "Access to postable denied");
|
break;
|
||||||
|
}
|
||||||
$res = (object)[
|
|
||||||
"count" => $object->getLikesCount(),
|
if (!$object || $object->isDeleted()) {
|
||||||
"items" => []
|
$this->fail(56, "Invalid postable");
|
||||||
];
|
}
|
||||||
|
|
||||||
$likers = array_slice(iterator_to_array($object->getLikers(1, $offset + $count)), $offset);
|
if (!$object->canBeViewedBy($this->getUser())) {
|
||||||
|
$this->fail(665, "Access to postable denied");
|
||||||
foreach($likers as $liker) {
|
}
|
||||||
if($skip_own && $liker->getId() == $this->getUser()->getId())
|
|
||||||
continue;
|
$res = (object) [
|
||||||
|
"count" => $object->getLikesCount(),
|
||||||
if(!$extended)
|
"items" => [],
|
||||||
$res->items[] = $liker->getId();
|
];
|
||||||
else
|
|
||||||
$res->items[] = $liker->toVkApiStruct(NULL, 'photo_50');
|
$likers = array_slice(iterator_to_array($object->getLikers(1, $offset + $count)), $offset);
|
||||||
}
|
|
||||||
|
foreach ($likers as $liker) {
|
||||||
return $res;
|
if ($skip_own && $liker->getId() == $this->getUser()->getId()) {
|
||||||
}
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$extended) {
|
||||||
|
$res->items[] = $liker->getId();
|
||||||
|
} else {
|
||||||
|
$res->items[] = $liker->toVkApiStruct(null, 'photo_50');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use openvk\Web\Events\NewMessageEvent;
|
use openvk\Web\Events\NewMessageEvent;
|
||||||
use openvk\Web\Models\Entities\{Correspondence, Message};
|
use openvk\Web\Models\Entities\{Correspondence, Message};
|
||||||
use openvk\Web\Models\Repositories\{Messages as MSGRepo, Users as USRRepo};
|
use openvk\Web\Models\Repositories\{Messages as MSGRepo, Users as USRRepo};
|
||||||
|
@ -11,37 +15,39 @@ final class Messages extends VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
private function resolvePeer(int $user_id = -1, int $peer_id = -1): ?int
|
private function resolvePeer(int $user_id = -1, int $peer_id = -1): ?int
|
||||||
{
|
{
|
||||||
if($user_id === -1) {
|
if ($user_id === -1) {
|
||||||
if($peer_id === -1)
|
if ($peer_id === -1) {
|
||||||
return NULL;
|
return null;
|
||||||
else if($peer_id < 0)
|
} elseif ($peer_id < 0) {
|
||||||
return NULL;
|
return null;
|
||||||
else if(($peer_id - 2000000000) > 0)
|
} elseif (($peer_id - 2000000000) > 0) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return $peer_id;
|
return $peer_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $user_id;
|
return $user_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getById(string $message_ids, int $preview_length = 0, int $extended = 0): object
|
public function getById(string $message_ids, int $preview_length = 0, int $extended = 0): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$msgs = new MSGRepo;
|
$msgs = new MSGRepo();
|
||||||
$ids = preg_split("%, ?%", $message_ids);
|
$ids = preg_split("%, ?%", $message_ids);
|
||||||
$items = [];
|
$items = [];
|
||||||
foreach($ids as $id) {
|
foreach ($ids as $id) {
|
||||||
$message = $msgs->get((int) $id);
|
$message = $msgs->get((int) $id);
|
||||||
if(!$message)
|
if (!$message) {
|
||||||
continue;
|
continue;
|
||||||
else if($message->getSender()->getId() !== $this->getUser()->getId() && $message->getRecipient()->getId() !== $this->getUser()->getId())
|
} elseif ($message->getSender()->getId() !== $this->getUser()->getId() && $message->getRecipient()->getId() !== $this->getUser()->getId()) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$author = $message->getSender()->getId() === $this->getUser()->getId() ? $message->getRecipient()->getId() : $message->getSender()->getId();
|
$author = $message->getSender()->getId() === $this->getUser()->getId() ? $message->getRecipient()->getId() : $message->getSender()->getId();
|
||||||
$rMsg = new APIMsg;
|
$rMsg = new APIMsg();
|
||||||
|
|
||||||
$rMsg->id = $message->getId();
|
$rMsg->id = $message->getId();
|
||||||
$rMsg->user_id = $author;
|
$rMsg->user_id = $author;
|
||||||
$rMsg->from_id = $message->getSender()->getId();
|
$rMsg->from_id = $message->getSender()->getId();
|
||||||
|
@ -51,167 +57,186 @@ final class Messages extends VKAPIRequestHandler
|
||||||
$rMsg->body = $message->getText(false);
|
$rMsg->body = $message->getText(false);
|
||||||
$rMsg->text = $message->getText(false);
|
$rMsg->text = $message->getText(false);
|
||||||
$rMsg->emoji = true;
|
$rMsg->emoji = true;
|
||||||
|
|
||||||
if($preview_length > 0)
|
if ($preview_length > 0) {
|
||||||
$rMsg->body = ovk_proc_strtr($rMsg->body, $preview_length);
|
$rMsg->body = ovk_proc_strtr($rMsg->body, $preview_length);
|
||||||
$rMsg->text = ovk_proc_strtr($rMsg->text, $preview_length);
|
}
|
||||||
|
$rMsg->text = ovk_proc_strtr($rMsg->text, $preview_length);
|
||||||
|
|
||||||
$items[] = $rMsg;
|
$items[] = $rMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
"count" => sizeof($items),
|
"count" => sizeof($items),
|
||||||
"items" => $items,
|
"items" => $items,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function send(int $user_id = -1, int $peer_id = -1, string $domain = "", int $chat_id = -1, string $user_ids = "", string $message = "", int $sticker_id = -1, int $forGodSakePleaseDoNotReportAboutMyOnlineActivity = 0,
|
public function send(
|
||||||
string $attachment = "") # интересно почему не attachments
|
int $user_id = -1,
|
||||||
{
|
int $peer_id = -1,
|
||||||
|
string $domain = "",
|
||||||
|
int $chat_id = -1,
|
||||||
|
string $user_ids = "",
|
||||||
|
string $message = "",
|
||||||
|
int $sticker_id = -1,
|
||||||
|
int $forGodSakePleaseDoNotReportAboutMyOnlineActivity = 0,
|
||||||
|
string $attachment = ""
|
||||||
|
) { # интересно почему не attachments
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
if($forGodSakePleaseDoNotReportAboutMyOnlineActivity == 0)
|
if ($forGodSakePleaseDoNotReportAboutMyOnlineActivity == 0) {
|
||||||
{
|
|
||||||
$this->getUser()->updOnline($this->getPlatform());
|
$this->getUser()->updOnline($this->getPlatform());
|
||||||
}
|
}
|
||||||
|
|
||||||
if($chat_id !== -1)
|
if ($chat_id !== -1) {
|
||||||
$this->fail(946, "Chats are not implemented");
|
$this->fail(946, "Chats are not implemented");
|
||||||
else if($sticker_id !== -1)
|
} elseif ($sticker_id !== -1) {
|
||||||
$this->fail(-151, "Stickers are not implemented");
|
$this->fail(-151, "Stickers are not implemented");
|
||||||
|
}
|
||||||
if(empty($message) && empty($attachment))
|
|
||||||
|
if (empty($message) && empty($attachment)) {
|
||||||
$this->fail(100, "Message text is empty or invalid");
|
$this->fail(100, "Message text is empty or invalid");
|
||||||
|
}
|
||||||
|
|
||||||
# lol recursion
|
# lol recursion
|
||||||
if(!empty($user_ids)) {
|
if (!empty($user_ids)) {
|
||||||
$rIds = [];
|
$rIds = [];
|
||||||
$ids = preg_split("%, ?%", $user_ids);
|
$ids = preg_split("%, ?%", $user_ids);
|
||||||
if(sizeof($ids) > 100)
|
if (sizeof($ids) > 100) {
|
||||||
$this->fail(913, "Too many recipients");
|
$this->fail(913, "Too many recipients");
|
||||||
|
|
||||||
foreach($ids as $id)
|
|
||||||
$rIds[] = $this->send(-1, $id, "", -1, "", $message);
|
|
||||||
|
|
||||||
return $rIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!empty($domain)) {
|
|
||||||
$peer = (new USRRepo)->getByShortCode($domain);
|
|
||||||
} else {
|
|
||||||
$peer = $this->resolvePeer($user_id, $peer_id);
|
|
||||||
$peer = (new USRRepo)->get($peer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$peer)
|
|
||||||
$this->fail(936, "There is no peer with this id");
|
|
||||||
|
|
||||||
if($this->getUser()->getId() !== $peer->getId() && !$peer->getPrivacyPermission('messages.write', $this->getUser()))
|
|
||||||
$this->fail(945, "This chat is disabled because of privacy settings");
|
|
||||||
|
|
||||||
# Finally we get to send a message!
|
|
||||||
$chat = new Correspondence($this->getUser(), $peer);
|
|
||||||
$msg = new Message;
|
|
||||||
$msg->setContent($message);
|
|
||||||
|
|
||||||
$msg = $chat->sendMessage($msg, true);
|
|
||||||
if(!$msg)
|
|
||||||
$this->fail(950, "Internal error");
|
|
||||||
else
|
|
||||||
if(!empty($attachment)) {
|
|
||||||
$attachs = parseAttachments($attachment);
|
|
||||||
|
|
||||||
# Работают только фотки, остальное просто не будет отображаться.
|
|
||||||
if(sizeof($attachs) >= 10)
|
|
||||||
$this->fail(15, "Too many attachments");
|
|
||||||
|
|
||||||
foreach($attachs as $attach) {
|
|
||||||
if($attach && !$attach->isDeleted() && $attach->getOwner()->getId() == $this->getUser()->getId())
|
|
||||||
$msg->attach($attach);
|
|
||||||
else
|
|
||||||
$this->fail(52, "One of the attachments is invalid");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $msg->getId();
|
foreach ($ids as $id) {
|
||||||
|
$rIds[] = $this->send(-1, $id, "", -1, "", $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($domain)) {
|
||||||
|
$peer = (new USRRepo())->getByShortCode($domain);
|
||||||
|
} else {
|
||||||
|
$peer = $this->resolvePeer($user_id, $peer_id);
|
||||||
|
$peer = (new USRRepo())->get($peer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$peer) {
|
||||||
|
$this->fail(936, "There is no peer with this id");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->getUser()->getId() !== $peer->getId() && !$peer->getPrivacyPermission('messages.write', $this->getUser())) {
|
||||||
|
$this->fail(945, "This chat is disabled because of privacy settings");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Finally we get to send a message!
|
||||||
|
$chat = new Correspondence($this->getUser(), $peer);
|
||||||
|
$msg = new Message();
|
||||||
|
$msg->setContent($message);
|
||||||
|
|
||||||
|
$msg = $chat->sendMessage($msg, true);
|
||||||
|
if (!$msg) {
|
||||||
|
$this->fail(950, "Internal error");
|
||||||
|
} elseif (!empty($attachment)) {
|
||||||
|
$attachs = parseAttachments($attachment);
|
||||||
|
|
||||||
|
# Работают только фотки, остальное просто не будет отображаться.
|
||||||
|
if (sizeof($attachs) >= 10) {
|
||||||
|
$this->fail(15, "Too many attachments");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($attachs as $attach) {
|
||||||
|
if ($attach && !$attach->isDeleted() && $attach->getOwner()->getId() == $this->getUser()->getId()) {
|
||||||
|
$msg->attach($attach);
|
||||||
|
} else {
|
||||||
|
$this->fail(52, "One of the attachments is invalid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $msg->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete(string $message_ids, int $spam = 0, int $delete_for_all = 0): object
|
public function delete(string $message_ids, int $spam = 0, int $delete_for_all = 0): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$msgs = new MSGRepo;
|
$msgs = new MSGRepo();
|
||||||
$ids = preg_split("%, ?%", $message_ids);
|
$ids = preg_split("%, ?%", $message_ids);
|
||||||
$items = [];
|
$items = [];
|
||||||
foreach($ids as $id) {
|
foreach ($ids as $id) {
|
||||||
$message = $msgs->get((int) $id);
|
$message = $msgs->get((int) $id);
|
||||||
if(!$message || $message->getSender()->getId() !== $this->getUser()->getId() && $message->getRecipient()->getId() !== $this->getUser()->getId())
|
if (!$message || $message->getSender()->getId() !== $this->getUser()->getId() && $message->getRecipient()->getId() !== $this->getUser()->getId()) {
|
||||||
$items[$id] = 0;
|
$items[$id] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
$message->delete();
|
$message->delete();
|
||||||
$items[$id] = 1;
|
$items[$id] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (object) $items;
|
return (object) $items;
|
||||||
}
|
}
|
||||||
|
|
||||||
function restore(int $message_id): int
|
public function restore(int $message_id): int
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$msg = (new MSGRepo)->get($message_id);
|
$msg = (new MSGRepo())->get($message_id);
|
||||||
if(!$msg)
|
if (!$msg) {
|
||||||
return 0;
|
return 0;
|
||||||
else if($msg->getSender()->getId() !== $this->getUser()->getId())
|
} elseif ($msg->getSender()->getId() !== $this->getUser()->getId()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
$msg->undelete();
|
$msg->undelete();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getConversations(int $offset = 0, int $count = 20, string $filter = "all", int $extended = 0, string $fields = ""): object
|
public function getConversations(int $offset = 0, int $count = 20, string $filter = "all", int $extended = 0, string $fields = ""): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$convos = (new MSGRepo)->getCorrespondencies($this->getUser(), -1, $count, $offset);
|
$convos = (new MSGRepo())->getCorrespondencies($this->getUser(), -1, $count, $offset);
|
||||||
$convosCount = (new MSGRepo)->getCorrespondenciesCount($this->getUser());
|
$convosCount = (new MSGRepo())->getCorrespondenciesCount($this->getUser());
|
||||||
$list = [];
|
$list = [];
|
||||||
|
|
||||||
$users = [];
|
$users = [];
|
||||||
foreach($convos as $convo) {
|
foreach ($convos as $convo) {
|
||||||
$correspondents = $convo->getCorrespondents();
|
$correspondents = $convo->getCorrespondents();
|
||||||
if($correspondents[0]->getId() === $this->getUser()->getId())
|
if ($correspondents[0]->getId() === $this->getUser()->getId()) {
|
||||||
$peer = $correspondents[1];
|
$peer = $correspondents[1];
|
||||||
else
|
} else {
|
||||||
$peer = $correspondents[0];
|
$peer = $correspondents[0];
|
||||||
|
}
|
||||||
|
|
||||||
$lastMessage = $convo->getPreviewMessage();
|
$lastMessage = $convo->getPreviewMessage();
|
||||||
|
|
||||||
$listConvo = new APIConvo;
|
$listConvo = new APIConvo();
|
||||||
$listConvo->peer = [
|
$listConvo->peer = [
|
||||||
"id" => $peer->getId(),
|
"id" => $peer->getId(),
|
||||||
"type" => "user",
|
"type" => "user",
|
||||||
"local_id" => $peer->getId(),
|
"local_id" => $peer->getId(),
|
||||||
];
|
];
|
||||||
|
|
||||||
$canWrite = $peer->getSubscriptionStatus($this->getUser()) === 3;
|
$canWrite = $peer->getSubscriptionStatus($this->getUser()) === 3;
|
||||||
$listConvo->can_write = [
|
$listConvo->can_write = [
|
||||||
"allowed" => $canWrite,
|
"allowed" => $canWrite,
|
||||||
];
|
];
|
||||||
|
|
||||||
$lastMessagePreview = NULL;
|
$lastMessagePreview = null;
|
||||||
if(!is_null($lastMessage)) {
|
if (!is_null($lastMessage)) {
|
||||||
$listConvo->last_message_id = $lastMessage->getId();
|
$listConvo->last_message_id = $lastMessage->getId();
|
||||||
|
|
||||||
if($lastMessage->getSender()->getId() === $this->getUser()->getId())
|
if ($lastMessage->getSender()->getId() === $this->getUser()->getId()) {
|
||||||
$author = $lastMessage->getRecipient()->getId();
|
$author = $lastMessage->getRecipient()->getId();
|
||||||
else
|
} else {
|
||||||
$author = $lastMessage->getSender()->getId();
|
$author = $lastMessage->getSender()->getId();
|
||||||
|
}
|
||||||
$lastMessagePreview = new APIMsg;
|
|
||||||
|
$lastMessagePreview = new APIMsg();
|
||||||
$lastMessagePreview->id = $lastMessage->getId();
|
$lastMessagePreview->id = $lastMessage->getId();
|
||||||
$lastMessagePreview->user_id = $author;
|
$lastMessagePreview->user_id = $author;
|
||||||
$lastMessagePreview->from_id = $lastMessage->getSender()->getId();
|
$lastMessagePreview->from_id = $lastMessage->getSender()->getId();
|
||||||
|
@ -221,19 +246,19 @@ final class Messages extends VKAPIRequestHandler
|
||||||
$lastMessagePreview->body = $lastMessage->getText(false);
|
$lastMessagePreview->body = $lastMessage->getText(false);
|
||||||
$lastMessagePreview->text = $lastMessage->getText(false);
|
$lastMessagePreview->text = $lastMessage->getText(false);
|
||||||
$lastMessagePreview->emoji = true;
|
$lastMessagePreview->emoji = true;
|
||||||
|
|
||||||
if($extended == 1) {
|
if ($extended == 1) {
|
||||||
$users[] = $author;
|
$users[] = $author;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$list[] = [
|
$list[] = [
|
||||||
"conversation" => $listConvo,
|
"conversation" => $listConvo,
|
||||||
"last_message" => $lastMessagePreview,
|
"last_message" => $lastMessagePreview,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if($extended == 0){
|
if ($extended == 0) {
|
||||||
return (object) [
|
return (object) [
|
||||||
"count" => $convosCount,
|
"count" => $convosCount,
|
||||||
"items" => $list,
|
"items" => $list,
|
||||||
|
@ -245,12 +270,12 @@ final class Messages extends VKAPIRequestHandler
|
||||||
return (object) [
|
return (object) [
|
||||||
"count" => $convosCount,
|
"count" => $convosCount,
|
||||||
"items" => $list,
|
"items" => $list,
|
||||||
"profiles" => (!empty($users) ? (new APIUsers)->get(implode(',', $users), $fields, 0, $count+1) : [])
|
"profiles" => (!empty($users) ? (new APIUsers())->get(implode(',', $users), $fields, 0, $count + 1) : []),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getConversationsById(string $peer_ids, int $extended = 0, string $fields = "")
|
public function getConversationsById(string $peer_ids, int $extended = 0, string $fields = "")
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
|
@ -258,21 +283,23 @@ final class Messages extends VKAPIRequestHandler
|
||||||
|
|
||||||
$output = [
|
$output = [
|
||||||
"count" => 0,
|
"count" => 0,
|
||||||
"items" => []
|
"items" => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
$userslist = [];
|
$userslist = [];
|
||||||
|
|
||||||
foreach($peers as $peer) {
|
foreach ($peers as $peer) {
|
||||||
if(key($peers) > 100)
|
if (key($peers) > 100) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(is_null($user_id = $this->resolvePeer((int) $peer)))
|
if (is_null($user_id = $this->resolvePeer((int) $peer))) {
|
||||||
$this->fail(-151, "Chats are not implemented");
|
$this->fail(-151, "Chats are not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
$user = (new USRRepo)->get((int) $peer);
|
$user = (new USRRepo())->get((int) $peer);
|
||||||
|
|
||||||
if($user) {
|
if ($user) {
|
||||||
$dialogue = new Correspondence($this->getUser(), $user);
|
$dialogue = new Correspondence($this->getUser(), $user);
|
||||||
$iterator = $dialogue->getMessages(Correspondence::CAP_BEHAVIOUR_START_MESSAGE_ID, 0, 1, 0, false);
|
$iterator = $dialogue->getMessages(Correspondence::CAP_BEHAVIOUR_START_MESSAGE_ID, 0, 1, 0, false);
|
||||||
$msg = $iterator[0]->unwrap(); // шоб удобнее было
|
$msg = $iterator[0]->unwrap(); // шоб удобнее было
|
||||||
|
@ -280,7 +307,7 @@ final class Messages extends VKAPIRequestHandler
|
||||||
"peer" => [
|
"peer" => [
|
||||||
"id" => $user->getId(),
|
"id" => $user->getId(),
|
||||||
"type" => "user",
|
"type" => "user",
|
||||||
"local_id" => $user->getId()
|
"local_id" => $user->getId(),
|
||||||
],
|
],
|
||||||
"last_message_id" => $msg->id,
|
"last_message_id" => $msg->id,
|
||||||
"in_read" => $msg->id,
|
"in_read" => $msg->id,
|
||||||
|
@ -295,41 +322,43 @@ final class Messages extends VKAPIRequestHandler
|
||||||
"is_marked_unread" => $iterator[0]->isUnread(),
|
"is_marked_unread" => $iterator[0]->isUnread(),
|
||||||
"important" => false, // целестора когда релиз
|
"important" => false, // целестора когда релиз
|
||||||
"can_write" => [
|
"can_write" => [
|
||||||
"allowed" => ($user->getId() === $this->getUser()->getId() || $user->getPrivacyPermission('messages.write', $this->getUser()) === true)
|
"allowed" => ($user->getId() === $this->getUser()->getId() || $user->getPrivacyPermission('messages.write', $this->getUser()) === true),
|
||||||
]
|
],
|
||||||
];
|
];
|
||||||
$userslist[] = $user->getId();
|
$userslist[] = $user->getId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($extended == 1) {
|
if ($extended == 1) {
|
||||||
$userslist = array_unique($userslist);
|
$userslist = array_unique($userslist);
|
||||||
$output['profiles'] = (!empty($userslist) ? (new APIUsers)->get(implode(',', $userslist), $fields) : []);
|
$output['profiles'] = (!empty($userslist) ? (new APIUsers())->get(implode(',', $userslist), $fields) : []);
|
||||||
}
|
}
|
||||||
|
|
||||||
$output['count'] = sizeof($output['items']);
|
$output['count'] = sizeof($output['items']);
|
||||||
return (object) $output;
|
return (object) $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHistory(int $offset = 0, int $count = 20, int $user_id = -1, int $peer_id = -1, int $start_message_id = 0, int $rev = 0, int $extended = 0, string $fields = ""): object
|
public function getHistory(int $offset = 0, int $count = 20, int $user_id = -1, int $peer_id = -1, int $start_message_id = 0, int $rev = 0, int $extended = 0, string $fields = ""): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
if(is_null($user_id = $this->resolvePeer($user_id, $peer_id)))
|
if (is_null($user_id = $this->resolvePeer($user_id, $peer_id))) {
|
||||||
$this->fail(-151, "Chats are not implemented");
|
$this->fail(-151, "Chats are not implemented");
|
||||||
|
}
|
||||||
$peer = (new USRRepo)->get($user_id);
|
|
||||||
if(!$peer)
|
$peer = (new USRRepo())->get($user_id);
|
||||||
|
if (!$peer) {
|
||||||
$this->fail(1, "ошибка про то что пира нет");
|
$this->fail(1, "ошибка про то что пира нет");
|
||||||
|
}
|
||||||
|
|
||||||
$results = [];
|
$results = [];
|
||||||
$dialogue = new Correspondence($this->getUser(), $peer);
|
$dialogue = new Correspondence($this->getUser(), $peer);
|
||||||
$iterator = $dialogue->getMessages(Correspondence::CAP_BEHAVIOUR_START_MESSAGE_ID, $start_message_id, $count, abs($offset), $rev === 1);
|
$iterator = $dialogue->getMessages(Correspondence::CAP_BEHAVIOUR_START_MESSAGE_ID, $start_message_id, $count, abs($offset), $rev === 1);
|
||||||
foreach($iterator as $message) {
|
foreach ($iterator as $message) {
|
||||||
$msgU = $message->unwrap(); # Why? As of OpenVK 2 Public Preview Two database layer doesn't work correctly and refuses to cache entities.
|
$msgU = $message->unwrap(); # Why? As of OpenVK 2 Public Preview Two database layer doesn't work correctly and refuses to cache entities.
|
||||||
# UPDATE: the issue seems to be caused by debug mode and json_encode (bruh_encode). ~~Dorothy
|
# UPDATE: the issue seems to be caused by debug mode and json_encode (bruh_encode). ~~Dorothy
|
||||||
|
|
||||||
$rMsg = new APIMsg;
|
$rMsg = new APIMsg();
|
||||||
$rMsg->id = $msgU->id;
|
$rMsg->id = $msgU->id;
|
||||||
$rMsg->user_id = $msgU->sender_id === $this->getUser()->getId() ? $msgU->recipient_id : $msgU->sender_id;
|
$rMsg->user_id = $msgU->sender_id === $this->getUser()->getId() ? $msgU->recipient_id : $msgU->sender_id;
|
||||||
$rMsg->from_id = $msgU->sender_id;
|
$rMsg->from_id = $msgU->sender_id;
|
||||||
|
@ -339,10 +368,10 @@ final class Messages extends VKAPIRequestHandler
|
||||||
$rMsg->body = $message->getText(false);
|
$rMsg->body = $message->getText(false);
|
||||||
$rMsg->text = $message->getText(false);
|
$rMsg->text = $message->getText(false);
|
||||||
$rMsg->emoji = true;
|
$rMsg->emoji = true;
|
||||||
|
|
||||||
$results[] = $rMsg;
|
$results[] = $rMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
$output = [
|
$output = [
|
||||||
"count" => sizeof($results),
|
"count" => sizeof($results),
|
||||||
"items" => $results,
|
"items" => $results,
|
||||||
|
@ -356,100 +385,111 @@ final class Messages extends VKAPIRequestHandler
|
||||||
|
|
||||||
return (object) $output;
|
return (object) $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLongPollHistory(int $ts = -1, int $preview_length = 0, int $events_limit = 1000, int $msgs_limit = 1000): object
|
public function getLongPollHistory(int $ts = -1, int $preview_length = 0, int $events_limit = 1000, int $msgs_limit = 1000): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$res = [
|
$res = [
|
||||||
"history" => [],
|
"history" => [],
|
||||||
"messages" => [],
|
"messages" => [],
|
||||||
"profiles" => [],
|
"profiles" => [],
|
||||||
"new_pts" => 0,
|
"new_pts" => 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
$manager = SignalManager::i();
|
$manager = SignalManager::i();
|
||||||
$events = $manager->getHistoryFor($this->getUser()->getId(), $ts === -1 ? NULL : $ts, min($events_limit, $msgs_limit));
|
$events = $manager->getHistoryFor($this->getUser()->getId(), $ts === -1 ? null : $ts, min($events_limit, $msgs_limit));
|
||||||
foreach($events as $event) {
|
foreach ($events as $event) {
|
||||||
if(!($event instanceof NewMessageEvent))
|
if (!($event instanceof NewMessageEvent)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$message = $this->getById((string) $event->getLongPoolSummary()->message["uuid"], $preview_length, 1)->items[0];
|
$message = $this->getById((string) $event->getLongPoolSummary()->message["uuid"], $preview_length, 1)->items[0];
|
||||||
if(!$message)
|
if (!$message) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$res["messages"][] = $message;
|
$res["messages"][] = $message;
|
||||||
$res["history"][] = $event->getVKAPISummary($this->getUser()->getId());
|
$res["history"][] = $event->getVKAPISummary($this->getUser()->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
$res["messages"] = [
|
$res["messages"] = [
|
||||||
"count" => sizeof($res["messages"]),
|
"count" => sizeof($res["messages"]),
|
||||||
"items" => $res["messages"],
|
"items" => $res["messages"],
|
||||||
];
|
];
|
||||||
return (object) $res;
|
return (object) $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLongPollServer(int $need_pts = 1, int $lp_version = 3, ?int $group_id = NULL): array
|
public function getLongPollServer(int $need_pts = 1, int $lp_version = 3, ?int $group_id = null): array
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
if($group_id > 0)
|
if ($group_id > 0) {
|
||||||
$this->fail(-151, "Not implemented");
|
$this->fail(-151, "Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
$url = "http" . (ovk_is_ssl() ? "s" : "") . "://$_SERVER[HTTP_HOST]/nim" . $this->getUser()->getId();
|
$url = "http" . (ovk_is_ssl() ? "s" : "") . "://$_SERVER[HTTP_HOST]/nim" . $this->getUser()->getId();
|
||||||
$key = openssl_random_pseudo_bytes(8);
|
$key = openssl_random_pseudo_bytes(8);
|
||||||
$key = bin2hex($key) . bin2hex($key ^ ( ~CHANDLER_ROOT_CONF["security"]["secret"] | ((string) $this->getUser()->getId()) ));
|
$key = bin2hex($key) . bin2hex($key ^ (~CHANDLER_ROOT_CONF["security"]["secret"] | ((string) $this->getUser()->getId())));
|
||||||
$res = [
|
$res = [
|
||||||
"key" => $key,
|
"key" => $key,
|
||||||
"server" => $url,
|
"server" => $url,
|
||||||
"ts" => time(),
|
"ts" => time(),
|
||||||
];
|
];
|
||||||
|
|
||||||
if($need_pts === 1)
|
if ($need_pts === 1) {
|
||||||
$res["pts"] = -1;
|
$res["pts"] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function edit(int $message_id, string $message = "", string $attachment = "", int $peer_id = 0)
|
public function edit(int $message_id, string $message = "", string $attachment = "", int $peer_id = 0)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$msg = (new MSGRepo)->get($message_id);
|
$msg = (new MSGRepo())->get($message_id);
|
||||||
|
|
||||||
if(empty($message) && empty($attachment))
|
if (empty($message) && empty($attachment)) {
|
||||||
$this->fail(100, "Required parameter 'message' missing.");
|
$this->fail(100, "Required parameter 'message' missing.");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$msg || $msg->isDeleted())
|
if (!$msg || $msg->isDeleted()) {
|
||||||
$this->fail(102, "Invalid message");
|
$this->fail(102, "Invalid message");
|
||||||
|
}
|
||||||
|
|
||||||
if($msg->getSender()->getId() != $this->getUser()->getId())
|
if ($msg->getSender()->getId() != $this->getUser()->getId()) {
|
||||||
$this->fail(15, "Access to message denied");
|
$this->fail(15, "Access to message denied");
|
||||||
|
}
|
||||||
if(!empty($message))
|
|
||||||
|
if (!empty($message)) {
|
||||||
$msg->setContent($message);
|
$msg->setContent($message);
|
||||||
|
}
|
||||||
|
|
||||||
$msg->setEdited(time());
|
$msg->setEdited(time());
|
||||||
$msg->save(true);
|
$msg->save(true);
|
||||||
|
|
||||||
if(!empty($attachment)) {
|
if (!empty($attachment)) {
|
||||||
$attachs = parseAttachments($attachment);
|
$attachs = parseAttachments($attachment);
|
||||||
$newAttachmentsCount = sizeof($attachs);
|
$newAttachmentsCount = sizeof($attachs);
|
||||||
|
|
||||||
$postsAttachments = iterator_to_array($msg->getChildren());
|
$postsAttachments = iterator_to_array($msg->getChildren());
|
||||||
|
|
||||||
if(sizeof($postsAttachments) >= 10)
|
if (sizeof($postsAttachments) >= 10) {
|
||||||
$this->fail(15, "Message have too many attachments");
|
$this->fail(15, "Message have too many attachments");
|
||||||
|
}
|
||||||
|
|
||||||
if(($newAttachmentsCount + sizeof($postsAttachments)) > 10)
|
if (($newAttachmentsCount + sizeof($postsAttachments)) > 10) {
|
||||||
$this->fail(158, "Message will have too many attachments");
|
$this->fail(158, "Message will have too many attachments");
|
||||||
|
}
|
||||||
|
|
||||||
foreach($attachs as $attach) {
|
foreach ($attachs as $attach) {
|
||||||
if($attach && !$attach->isDeleted() && $attach->getOwner()->getId() == $this->getUser()->getId())
|
if ($attach && !$attach->isDeleted() && $attach->getOwner()->getId() == $this->getUser()->getId()) {
|
||||||
$msg->attach($attach);
|
$msg->attach($attach);
|
||||||
else
|
} else {
|
||||||
$this->fail(52, "One of the attachments is invalid");
|
$this->fail(52, "One of the attachments is invalid");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,254 +1,273 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
namespace openvk\VKAPI\Handlers;
|
|
||||||
use Chandler\Database\DatabaseConnection;
|
declare(strict_types=1);
|
||||||
use openvk\Web\Models\Repositories\Posts as PostsRepo;
|
|
||||||
use openvk\Web\Models\Entities\User;
|
namespace openvk\VKAPI\Handlers;
|
||||||
use openvk\VKAPI\Handlers\Wall;
|
|
||||||
|
use Chandler\Database\DatabaseConnection;
|
||||||
final class Newsfeed extends VKAPIRequestHandler
|
use openvk\Web\Models\Repositories\Posts as PostsRepo;
|
||||||
{
|
use openvk\Web\Models\Entities\User;
|
||||||
function get(string $fields = "", int $start_from = 0, int $start_time = 0, int $end_time = 0, int $offset = 0, int $count = 30, int $extended = 0, int $forGodSakePleaseDoNotReportAboutMyOnlineActivity = 0)
|
use openvk\VKAPI\Handlers\Wall;
|
||||||
{
|
|
||||||
$this->requireUser();
|
final class Newsfeed extends VKAPIRequestHandler
|
||||||
|
{
|
||||||
if($forGodSakePleaseDoNotReportAboutMyOnlineActivity == 0)
|
public function get(string $fields = "", int $start_from = 0, int $start_time = 0, int $end_time = 0, int $offset = 0, int $count = 30, int $extended = 0, int $forGodSakePleaseDoNotReportAboutMyOnlineActivity = 0)
|
||||||
{
|
{
|
||||||
$this->getUser()->updOnline($this->getPlatform());
|
$this->requireUser();
|
||||||
}
|
|
||||||
|
if ($forGodSakePleaseDoNotReportAboutMyOnlineActivity == 0) {
|
||||||
$id = $this->getUser()->getId();
|
$this->getUser()->updOnline($this->getPlatform());
|
||||||
$subs = DatabaseConnection::i()
|
}
|
||||||
->getContext()
|
|
||||||
->table("subscriptions")
|
$id = $this->getUser()->getId();
|
||||||
->where("follower", $id);
|
$subs = DatabaseConnection::i()
|
||||||
$ids = array_map(function($rel) {
|
->getContext()
|
||||||
return $rel->target * ($rel->model === "openvk\Web\Models\Entities\User" ? 1 : -1);
|
->table("subscriptions")
|
||||||
}, iterator_to_array($subs));
|
->where("follower", $id);
|
||||||
$ids[] = $this->getUser()->getId();
|
$ids = array_map(function ($rel) {
|
||||||
|
return $rel->target * ($rel->model === "openvk\Web\Models\Entities\User" ? 1 : -1);
|
||||||
$posts = DatabaseConnection::i()
|
}, iterator_to_array($subs));
|
||||||
->getContext()
|
$ids[] = $this->getUser()->getId();
|
||||||
->table("posts")
|
|
||||||
->select("id")
|
$posts = DatabaseConnection::i()
|
||||||
->where("wall IN (?)", $ids)
|
->getContext()
|
||||||
->where("deleted", 0)
|
->table("posts")
|
||||||
->where("suggested", 0)
|
->select("id")
|
||||||
->where("id < (?)", empty($start_from) ? PHP_INT_MAX : $start_from)
|
->where("wall IN (?)", $ids)
|
||||||
->where("? <= created", empty($start_time) ? 0 : $start_time)
|
->where("deleted", 0)
|
||||||
->where("? >= created", empty($end_time) ? PHP_INT_MAX : $end_time)
|
->where("suggested", 0)
|
||||||
->order("created DESC");
|
->where("id < (?)", empty($start_from) ? PHP_INT_MAX : $start_from)
|
||||||
|
->where("? <= created", empty($start_time) ? 0 : $start_time)
|
||||||
$rposts = [];
|
->where("? >= created", empty($end_time) ? PHP_INT_MAX : $end_time)
|
||||||
foreach($posts->page((int) ($offset + 1), $count) as $post)
|
->order("created DESC");
|
||||||
$rposts[] = (new PostsRepo)->get($post->id)->getPrettyId();
|
|
||||||
|
$rposts = [];
|
||||||
$response = (new Wall)->getById(implode(',', $rposts), $extended, $fields, $this->getUser());
|
foreach ($posts->page((int) ($offset + 1), $count) as $post) {
|
||||||
$response->next_from = end(end($posts->page((int) ($offset + 1), $count))); // ну и костыли пиздец конечно)
|
$rposts[] = (new PostsRepo())->get($post->id)->getPrettyId();
|
||||||
|
}
|
||||||
return $response;
|
|
||||||
}
|
$response = (new Wall())->getById(implode(',', $rposts), $extended, $fields, $this->getUser());
|
||||||
|
$response->next_from = end(end($posts->page((int) ($offset + 1), $count))); // ну и костыли пиздец конечно)
|
||||||
function getGlobal(string $fields = "", int $start_from = 0, int $start_time = 0, int $end_time = 0, int $offset = 0, int $count = 30, int $extended = 0, int $rss = 0)
|
|
||||||
{
|
return $response;
|
||||||
$this->requireUser();
|
}
|
||||||
|
|
||||||
$queryBase = "FROM `posts` LEFT JOIN `groups` ON GREATEST(`posts`.`wall`, 0) = 0 AND `groups`.`id` = ABS(`posts`.`wall`) LEFT JOIN `profiles` ON LEAST(`posts`.`wall`, 0) = 0 AND `profiles`.`id` = ABS(`posts`.`wall`)";
|
public function getGlobal(string $fields = "", int $start_from = 0, int $start_time = 0, int $end_time = 0, int $offset = 0, int $count = 30, int $extended = 0, int $rss = 0)
|
||||||
$queryBase .= "WHERE (`groups`.`hide_from_global_feed` = 0 OR `groups`.`name` IS NULL) AND (`profiles`.`profile_type` = 0 OR `profiles`.`first_name` IS NULL) AND `posts`.`deleted` = 0 AND `posts`.`suggested` = 0";
|
{
|
||||||
|
$this->requireUser();
|
||||||
if($this->getUser()->getNsfwTolerance() === User::NSFW_INTOLERANT)
|
|
||||||
$queryBase .= " AND `nsfw` = 0";
|
$queryBase = "FROM `posts` LEFT JOIN `groups` ON GREATEST(`posts`.`wall`, 0) = 0 AND `groups`.`id` = ABS(`posts`.`wall`) LEFT JOIN `profiles` ON LEAST(`posts`.`wall`, 0) = 0 AND `profiles`.`id` = ABS(`posts`.`wall`)";
|
||||||
|
$queryBase .= "WHERE (`groups`.`hide_from_global_feed` = 0 OR `groups`.`name` IS NULL) AND (`profiles`.`profile_type` = 0 OR `profiles`.`first_name` IS NULL) AND `posts`.`deleted` = 0 AND `posts`.`suggested` = 0";
|
||||||
if($return_banned == 0) {
|
|
||||||
$ignored_sources_ids = $this->getUser()->getIgnoredSources(0, OPENVK_ROOT_CONF['openvk']['preferences']['newsfeed']['ignoredSourcesLimit'] ?? 50, true);
|
if ($this->getUser()->getNsfwTolerance() === User::NSFW_INTOLERANT) {
|
||||||
|
$queryBase .= " AND `nsfw` = 0";
|
||||||
if(sizeof($ignored_sources_ids) > 0) {
|
}
|
||||||
$imploded_ids = implode("', '", $ignored_sources_ids);
|
|
||||||
$queryBase .= " AND `posts`.`wall` NOT IN ('$imploded_ids')";
|
if ($return_banned == 0) {
|
||||||
}
|
$ignored_sources_ids = $this->getUser()->getIgnoredSources(0, OPENVK_ROOT_CONF['openvk']['preferences']['newsfeed']['ignoredSourcesLimit'] ?? 50, true);
|
||||||
}
|
|
||||||
|
if (sizeof($ignored_sources_ids) > 0) {
|
||||||
$start_from = empty($start_from) ? PHP_INT_MAX : $start_from;
|
$imploded_ids = implode("', '", $ignored_sources_ids);
|
||||||
$start_time = empty($start_time) ? 0 : $start_time;
|
$queryBase .= " AND `posts`.`wall` NOT IN ('$imploded_ids')";
|
||||||
$end_time = empty($end_time) ? PHP_INT_MAX : $end_time;
|
}
|
||||||
$posts = DatabaseConnection::i()->getConnection()->query("SELECT `posts`.`id` " . $queryBase . " AND `posts`.`id` <= " . $start_from . " AND " . $start_time . " <= `posts`.`created` AND `posts`.`created` <= " . $end_time . " ORDER BY `created` DESC LIMIT " . $count . " OFFSET " . $offset);
|
}
|
||||||
|
|
||||||
$rposts = [];
|
$start_from = empty($start_from) ? PHP_INT_MAX : $start_from;
|
||||||
$ids = [];
|
$start_time = empty($start_time) ? 0 : $start_time;
|
||||||
if($rss == 1) {
|
$end_time = empty($end_time) ? PHP_INT_MAX : $end_time;
|
||||||
$channel = new \Bhaktaraz\RSSGenerator\Channel();
|
$posts = DatabaseConnection::i()->getConnection()->query("SELECT `posts`.`id` " . $queryBase . " AND `posts`.`id` <= " . $start_from . " AND " . $start_time . " <= `posts`.`created` AND `posts`.`created` <= " . $end_time . " ORDER BY `created` DESC LIMIT " . $count . " OFFSET " . $offset);
|
||||||
$channel->title("Global Feed — " . OPENVK_ROOT_CONF['openvk']['appearance']['name'])
|
|
||||||
->description('OVK Global feed')
|
$rposts = [];
|
||||||
->url(ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/feed/all");
|
$ids = [];
|
||||||
|
if ($rss == 1) {
|
||||||
foreach($posts as $item) {
|
$channel = new \Bhaktaraz\RSSGenerator\Channel();
|
||||||
$post = (new PostsRepo)->get($item->id);
|
$channel->title("Global Feed — " . OPENVK_ROOT_CONF['openvk']['appearance']['name'])
|
||||||
if(!$post || $post->isDeleted()) {
|
->description('OVK Global feed')
|
||||||
continue;
|
->url(ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/feed/all");
|
||||||
}
|
|
||||||
|
foreach ($posts as $item) {
|
||||||
$output = $post->toRss();
|
$post = (new PostsRepo())->get($item->id);
|
||||||
$output->appendTo($channel);
|
if (!$post || $post->isDeleted()) {
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
return $channel;
|
|
||||||
}
|
$output = $post->toRss();
|
||||||
|
$output->appendTo($channel);
|
||||||
foreach($posts as $post) {
|
}
|
||||||
$rposts[] = (new PostsRepo)->get($post->id)->getPrettyId();
|
|
||||||
$ids[] = $post->id;
|
return $channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = (new Wall)->getById(implode(',', $rposts), $extended, $fields, $this->getUser());
|
foreach ($posts as $post) {
|
||||||
$response->next_from = end($ids);
|
$rposts[] = (new PostsRepo())->get($post->id)->getPrettyId();
|
||||||
|
$ids[] = $post->id;
|
||||||
return $response;
|
}
|
||||||
}
|
|
||||||
|
$response = (new Wall())->getById(implode(',', $rposts), $extended, $fields, $this->getUser());
|
||||||
function getByType(string $feed_type = 'top', string $fields = "", int $start_from = 0, int $start_time = 0, int $end_time = 0, int $offset = 0, int $count = 30, int $extended = 0, int $return_banned = 0)
|
$response->next_from = end($ids);
|
||||||
{
|
|
||||||
$this->requireUser();
|
return $response;
|
||||||
|
}
|
||||||
switch($feed_type) {
|
|
||||||
case 'top':
|
public function getByType(string $feed_type = 'top', string $fields = "", int $start_from = 0, int $start_time = 0, int $end_time = 0, int $offset = 0, int $count = 30, int $extended = 0, int $return_banned = 0)
|
||||||
return $this->getGlobal($fields, $start_from, $start_time, $end_time, $offset, $count, $extended, $return_banned);
|
{
|
||||||
break;
|
$this->requireUser();
|
||||||
default:
|
|
||||||
return $this->get($fields, $start_from, $start_time, $end_time, $offset, $count, $extended);
|
switch ($feed_type) {
|
||||||
break;
|
case 'top':
|
||||||
}
|
return $this->getGlobal($fields, $start_from, $start_time, $end_time, $offset, $count, $extended, $return_banned);
|
||||||
}
|
break;
|
||||||
|
default:
|
||||||
function getBanned(int $extended = 0, string $fields = "", string $name_case = "nom", int $merge = 0): object
|
return $this->get($fields, $start_from, $start_time, $end_time, $offset, $count, $extended);
|
||||||
{
|
break;
|
||||||
$this->requireUser();
|
}
|
||||||
|
}
|
||||||
$offset = 0;
|
|
||||||
$count = OPENVK_ROOT_CONF['openvk']['preferences']['newsfeed']['ignoredSourcesLimit'] ?? 50;
|
public function getBanned(int $extended = 0, string $fields = "", string $name_case = "nom", int $merge = 0): object
|
||||||
$banned = $this->getUser()->getIgnoredSources($offset, $count, ($extended != 1));
|
{
|
||||||
$return_object = (object) [
|
$this->requireUser();
|
||||||
'groups' => [],
|
|
||||||
'members' => [],
|
$offset = 0;
|
||||||
];
|
$count = OPENVK_ROOT_CONF['openvk']['preferences']['newsfeed']['ignoredSourcesLimit'] ?? 50;
|
||||||
|
$banned = $this->getUser()->getIgnoredSources($offset, $count, ($extended != 1));
|
||||||
if($extended == 0) {
|
$return_object = (object) [
|
||||||
foreach($banned as $ban) {
|
'groups' => [],
|
||||||
if($ban > 0)
|
'members' => [],
|
||||||
$return_object->members[] = $ban;
|
];
|
||||||
else
|
|
||||||
$return_object->groups[] = $ban;
|
if ($extended == 0) {
|
||||||
}
|
foreach ($banned as $ban) {
|
||||||
} else {
|
if ($ban > 0) {
|
||||||
if($merge == 1) {
|
$return_object->members[] = $ban;
|
||||||
$return_object = (object) [
|
} else {
|
||||||
'count' => sizeof($banned),
|
$return_object->groups[] = $ban;
|
||||||
'items' => [],
|
}
|
||||||
];
|
}
|
||||||
|
} else {
|
||||||
foreach($banned as $ban) {
|
if ($merge == 1) {
|
||||||
$return_object->items[] = $ban->toVkApiStruct($this->getUser(), $fields);
|
$return_object = (object) [
|
||||||
}
|
'count' => sizeof($banned),
|
||||||
} else {
|
'items' => [],
|
||||||
$return_object = (object) [
|
];
|
||||||
'groups' => [],
|
|
||||||
'profiles' => [],
|
foreach ($banned as $ban) {
|
||||||
];
|
$return_object->items[] = $ban->toVkApiStruct($this->getUser(), $fields);
|
||||||
|
}
|
||||||
foreach($banned as $ban) {
|
} else {
|
||||||
if($ban->getRealId() > 0)
|
$return_object = (object) [
|
||||||
$return_object->profiles[] = $ban->toVkApiStruct($this->getUser(), $fields);
|
'groups' => [],
|
||||||
else
|
'profiles' => [],
|
||||||
$return_object->groups[] = $ban->toVkApiStruct($this->getUser(), $fields);
|
];
|
||||||
}
|
|
||||||
}
|
foreach ($banned as $ban) {
|
||||||
}
|
if ($ban->getRealId() > 0) {
|
||||||
|
$return_object->profiles[] = $ban->toVkApiStruct($this->getUser(), $fields);
|
||||||
return $return_object;
|
} else {
|
||||||
}
|
$return_object->groups[] = $ban->toVkApiStruct($this->getUser(), $fields);
|
||||||
|
}
|
||||||
function addBan(string $user_ids = "", string $group_ids = "")
|
}
|
||||||
{
|
}
|
||||||
$this->requireUser();
|
}
|
||||||
$this->willExecuteWriteAction();
|
|
||||||
|
return $return_object;
|
||||||
# Formatting input ids
|
}
|
||||||
if(!empty($user_ids)) {
|
|
||||||
$user_ids = array_map(function($el) {
|
public function addBan(string $user_ids = "", string $group_ids = "")
|
||||||
return (int)$el;
|
{
|
||||||
}, explode(',', $user_ids));
|
$this->requireUser();
|
||||||
$user_ids = array_unique($user_ids);
|
$this->willExecuteWriteAction();
|
||||||
} else
|
|
||||||
$user_ids = [];
|
# Formatting input ids
|
||||||
|
if (!empty($user_ids)) {
|
||||||
if(!empty($group_ids)) {
|
$user_ids = array_map(function ($el) {
|
||||||
$group_ids = array_map(function($el) {
|
return (int) $el;
|
||||||
return abs((int)$el) * -1;
|
}, explode(',', $user_ids));
|
||||||
}, explode(',', $group_ids));
|
$user_ids = array_unique($user_ids);
|
||||||
$group_ids = array_unique($group_ids);
|
} else {
|
||||||
} else
|
$user_ids = [];
|
||||||
$group_ids = [];
|
}
|
||||||
|
|
||||||
$ids = array_merge($user_ids, $group_ids);
|
if (!empty($group_ids)) {
|
||||||
if(sizeof($ids) < 1)
|
$group_ids = array_map(function ($el) {
|
||||||
return 0;
|
return abs((int) $el) * -1;
|
||||||
|
}, explode(',', $group_ids));
|
||||||
if(sizeof($ids) > 10)
|
$group_ids = array_unique($group_ids);
|
||||||
$this->fail(-10, "Limit of 'ids' is 10");
|
} else {
|
||||||
|
$group_ids = [];
|
||||||
$config_limit = OPENVK_ROOT_CONF['openvk']['preferences']['newsfeed']['ignoredSourcesLimit'] ?? 50;
|
}
|
||||||
$user_ignores = $this->getUser()->getIgnoredSourcesCount();
|
|
||||||
if(($user_ignores + sizeof($ids)) > $config_limit) {
|
$ids = array_merge($user_ids, $group_ids);
|
||||||
$this->fail(-50, "Ignoring limit exceeded");
|
if (sizeof($ids) < 1) {
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
$entities = get_entities($ids);
|
|
||||||
$successes = 0;
|
if (sizeof($ids) > 10) {
|
||||||
foreach($entities as $entity) {
|
$this->fail(-10, "Limit of 'ids' is 10");
|
||||||
if(!$entity || $entity->getRealId() === $this->getUser()->getRealId() || $entity->isHideFromGlobalFeedEnabled() || $entity->isIgnoredBy($this->getUser())) continue;
|
}
|
||||||
|
|
||||||
$entity->addIgnore($this->getUser());
|
$config_limit = OPENVK_ROOT_CONF['openvk']['preferences']['newsfeed']['ignoredSourcesLimit'] ?? 50;
|
||||||
$successes += 1;
|
$user_ignores = $this->getUser()->getIgnoredSourcesCount();
|
||||||
}
|
if (($user_ignores + sizeof($ids)) > $config_limit) {
|
||||||
|
$this->fail(-50, "Ignoring limit exceeded");
|
||||||
return 1;
|
}
|
||||||
}
|
|
||||||
|
$entities = get_entities($ids);
|
||||||
function deleteBan(string $user_ids = "", string $group_ids = "")
|
$successes = 0;
|
||||||
{
|
foreach ($entities as $entity) {
|
||||||
$this->requireUser();
|
if (!$entity || $entity->getRealId() === $this->getUser()->getRealId() || $entity->isHideFromGlobalFeedEnabled() || $entity->isIgnoredBy($this->getUser())) {
|
||||||
$this->willExecuteWriteAction();
|
continue;
|
||||||
|
}
|
||||||
if(!empty($user_ids)) {
|
|
||||||
$user_ids = array_map(function($el) {
|
$entity->addIgnore($this->getUser());
|
||||||
return (int)$el;
|
$successes += 1;
|
||||||
}, explode(',', $user_ids));
|
}
|
||||||
$user_ids = array_unique($user_ids);
|
|
||||||
} else
|
return 1;
|
||||||
$user_ids = [];
|
}
|
||||||
|
|
||||||
if(!empty($group_ids)) {
|
public function deleteBan(string $user_ids = "", string $group_ids = "")
|
||||||
$group_ids = array_map(function($el) {
|
{
|
||||||
return abs((int)$el) * -1;
|
$this->requireUser();
|
||||||
}, explode(',', $group_ids));
|
$this->willExecuteWriteAction();
|
||||||
$group_ids = array_unique($group_ids);
|
|
||||||
} else
|
if (!empty($user_ids)) {
|
||||||
$group_ids = [];
|
$user_ids = array_map(function ($el) {
|
||||||
|
return (int) $el;
|
||||||
$ids = array_merge($user_ids, $group_ids);
|
}, explode(',', $user_ids));
|
||||||
if(sizeof($ids) < 1)
|
$user_ids = array_unique($user_ids);
|
||||||
return 0;
|
} else {
|
||||||
|
$user_ids = [];
|
||||||
if(sizeof($ids) > 10)
|
}
|
||||||
$this->fail(-10, "Limit of ids is 10");
|
|
||||||
|
if (!empty($group_ids)) {
|
||||||
$entities = get_entities($ids);
|
$group_ids = array_map(function ($el) {
|
||||||
$successes = 0;
|
return abs((int) $el) * -1;
|
||||||
foreach($entities as $entity) {
|
}, explode(',', $group_ids));
|
||||||
if(!$entity || $entity->getRealId() === $this->getUser()->getRealId() || !$entity->isIgnoredBy($this->getUser())) continue;
|
$group_ids = array_unique($group_ids);
|
||||||
|
} else {
|
||||||
$entity->removeIgnore($this->getUser());
|
$group_ids = [];
|
||||||
$successes += 1;
|
}
|
||||||
}
|
|
||||||
|
$ids = array_merge($user_ids, $group_ids);
|
||||||
return 1;
|
if (sizeof($ids) < 1) {
|
||||||
}
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sizeof($ids) > 10) {
|
||||||
|
$this->fail(-10, "Limit of ids is 10");
|
||||||
|
}
|
||||||
|
|
||||||
|
$entities = get_entities($ids);
|
||||||
|
$successes = 0;
|
||||||
|
foreach ($entities as $entity) {
|
||||||
|
if (!$entity || $entity->getRealId() === $this->getUser()->getRealId() || !$entity->isIgnoredBy($this->getUser())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$entity->removeIgnore($this->getUser());
|
||||||
|
$successes += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use openvk\Web\Models\Repositories\Notes as NotesRepo;
|
use openvk\Web\Models\Repositories\Notes as NotesRepo;
|
||||||
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
||||||
use openvk\Web\Models\Repositories\Comments as CommentsRepo;
|
use openvk\Web\Models\Repositories\Comments as CommentsRepo;
|
||||||
|
@ -9,12 +13,12 @@ use openvk\Web\Models\Entities\{Note, Comment};
|
||||||
|
|
||||||
final class Notes extends VKAPIRequestHandler
|
final class Notes extends VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
function add(string $title, string $text, int $privacy = 0, int $comment_privacy = 0, string $privacy_view = "", string $privacy_comment = "")
|
public function add(string $title, string $text, int $privacy = 0, int $comment_privacy = 0, string $privacy_view = "", string $privacy_comment = "")
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$note = new Note;
|
$note = new Note();
|
||||||
$note->setOwner($this->getUser()->getId());
|
$note->setOwner($this->getUser()->getId());
|
||||||
$note->setCreated(time());
|
$note->setCreated(time());
|
||||||
$note->setName($title);
|
$note->setName($title);
|
||||||
|
@ -25,31 +29,37 @@ final class Notes extends VKAPIRequestHandler
|
||||||
return $note->getVirtualId();
|
return $note->getVirtualId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function createComment(string $note_id, int $owner_id, string $message, int $reply_to = 0, string $attachments = "")
|
public function createComment(string $note_id, int $owner_id, string $message, int $reply_to = 0, string $attachments = "")
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
$note = (new NotesRepo)->getNoteById((int)$owner_id, (int)$note_id);
|
$note = (new NotesRepo())->getNoteById((int) $owner_id, (int) $note_id);
|
||||||
|
|
||||||
if(!$note)
|
if (!$note) {
|
||||||
$this->fail(180, "Note not found");
|
$this->fail(180, "Note not found");
|
||||||
|
}
|
||||||
if($note->isDeleted())
|
|
||||||
|
if ($note->isDeleted()) {
|
||||||
$this->fail(189, "Note is deleted");
|
$this->fail(189, "Note is deleted");
|
||||||
|
}
|
||||||
if($note->getOwner()->isDeleted())
|
|
||||||
|
if ($note->getOwner()->isDeleted()) {
|
||||||
$this->fail(403, "Owner is deleted");
|
$this->fail(403, "Owner is deleted");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$note->canBeViewedBy($this->getUser()))
|
if (!$note->canBeViewedBy($this->getUser())) {
|
||||||
$this->fail(15, "Access denied");
|
$this->fail(15, "Access denied");
|
||||||
|
}
|
||||||
if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser()))
|
|
||||||
|
if (!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser())) {
|
||||||
$this->fail(43, "No access");
|
$this->fail(43, "No access");
|
||||||
|
}
|
||||||
|
|
||||||
if(empty($message) && empty($attachments))
|
if (empty($message) && empty($attachments)) {
|
||||||
$this->fail(100, "Required parameter 'message' missing.");
|
$this->fail(100, "Required parameter 'message' missing.");
|
||||||
|
}
|
||||||
|
|
||||||
$comment = new Comment;
|
$comment = new Comment();
|
||||||
$comment->setOwner($this->getUser()->getId());
|
$comment->setOwner($this->getUser()->getId());
|
||||||
$comment->setModel(get_class($note));
|
$comment->setModel(get_class($note));
|
||||||
$comment->setTarget($note->getId());
|
$comment->setTarget($note->getId());
|
||||||
|
@ -57,43 +67,49 @@ final class Notes extends VKAPIRequestHandler
|
||||||
$comment->setCreated(time());
|
$comment->setCreated(time());
|
||||||
$comment->save();
|
$comment->save();
|
||||||
|
|
||||||
if(!empty($attachments)) {
|
if (!empty($attachments)) {
|
||||||
$attachmentsArr = explode(",", $attachments);
|
$attachmentsArr = explode(",", $attachments);
|
||||||
|
|
||||||
if(sizeof($attachmentsArr) > 10)
|
if (sizeof($attachmentsArr) > 10) {
|
||||||
$this->fail(50, "Error: too many attachments");
|
$this->fail(50, "Error: too many attachments");
|
||||||
|
}
|
||||||
foreach($attachmentsArr as $attac) {
|
|
||||||
$attachmentType = NULL;
|
|
||||||
|
|
||||||
if(str_contains($attac, "photo"))
|
foreach ($attachmentsArr as $attac) {
|
||||||
|
$attachmentType = null;
|
||||||
|
|
||||||
|
if (str_contains($attac, "photo")) {
|
||||||
$attachmentType = "photo";
|
$attachmentType = "photo";
|
||||||
elseif(str_contains($attac, "video"))
|
} elseif (str_contains($attac, "video")) {
|
||||||
$attachmentType = "video";
|
$attachmentType = "video";
|
||||||
else
|
} else {
|
||||||
$this->fail(205, "Unknown attachment type");
|
$this->fail(205, "Unknown attachment type");
|
||||||
|
}
|
||||||
|
|
||||||
$attachment = str_replace($attachmentType, "", $attac);
|
$attachment = str_replace($attachmentType, "", $attac);
|
||||||
|
|
||||||
$attachmentOwner = (int)explode("_", $attachment)[0];
|
$attachmentOwner = (int) explode("_", $attachment)[0];
|
||||||
$attachmentId = (int)end(explode("_", $attachment));
|
$attachmentId = (int) end(explode("_", $attachment));
|
||||||
|
|
||||||
$attacc = NULL;
|
$attacc = null;
|
||||||
|
|
||||||
if($attachmentType == "photo") {
|
if ($attachmentType == "photo") {
|
||||||
$attacc = (new PhotosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId);
|
$attacc = (new PhotosRepo())->getByOwnerAndVID($attachmentOwner, $attachmentId);
|
||||||
if(!$attacc || $attacc->isDeleted())
|
if (!$attacc || $attacc->isDeleted()) {
|
||||||
$this->fail(100, "Photo does not exists");
|
$this->fail(100, "Photo does not exists");
|
||||||
if($attacc->getOwner()->getId() != $this->getUser()->getId())
|
}
|
||||||
|
if ($attacc->getOwner()->getId() != $this->getUser()->getId()) {
|
||||||
$this->fail(43, "You do not have access to this photo");
|
$this->fail(43, "You do not have access to this photo");
|
||||||
|
}
|
||||||
|
|
||||||
$comment->attach($attacc);
|
$comment->attach($attacc);
|
||||||
} elseif($attachmentType == "video") {
|
} elseif ($attachmentType == "video") {
|
||||||
$attacc = (new VideosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId);
|
$attacc = (new VideosRepo())->getByOwnerAndVID($attachmentOwner, $attachmentId);
|
||||||
if(!$attacc || $attacc->isDeleted())
|
if (!$attacc || $attacc->isDeleted()) {
|
||||||
$this->fail(100, "Video does not exists");
|
$this->fail(100, "Video does not exists");
|
||||||
if($attacc->getOwner()->getId() != $this->getUser()->getId())
|
}
|
||||||
|
if ($attacc->getOwner()->getId() != $this->getUser()->getId()) {
|
||||||
$this->fail(43, "You do not have access to this video");
|
$this->fail(43, "You do not have access to this video");
|
||||||
|
}
|
||||||
|
|
||||||
$comment->attach($attacc);
|
$comment->attach($attacc);
|
||||||
}
|
}
|
||||||
|
@ -103,87 +119,96 @@ final class Notes extends VKAPIRequestHandler
|
||||||
return $comment->getId();
|
return $comment->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete(string $note_id)
|
public function delete(string $note_id)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$note = (new NotesRepo)->get((int)$note_id);
|
$note = (new NotesRepo())->get((int) $note_id);
|
||||||
|
|
||||||
if(!$note)
|
if (!$note) {
|
||||||
$this->fail(180, "Note not found");
|
$this->fail(180, "Note not found");
|
||||||
|
}
|
||||||
if(!$note->canBeModifiedBy($this->getUser()))
|
|
||||||
|
if (!$note->canBeModifiedBy($this->getUser())) {
|
||||||
$this->fail(15, "Access to note denied");
|
$this->fail(15, "Access to note denied");
|
||||||
|
}
|
||||||
|
|
||||||
$note->delete();
|
$note->delete();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function edit(string $note_id, string $title = "", string $text = "", int $privacy = 0, int $comment_privacy = 0, string $privacy_view = "", string $privacy_comment = "")
|
public function edit(string $note_id, string $title = "", string $text = "", int $privacy = 0, int $comment_privacy = 0, string $privacy_view = "", string $privacy_comment = "")
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$note = (new NotesRepo)->getNoteById($this->getUser()->getId(), (int)$note_id);
|
$note = (new NotesRepo())->getNoteById($this->getUser()->getId(), (int) $note_id);
|
||||||
|
|
||||||
if(!$note)
|
if (!$note) {
|
||||||
$this->fail(180, "Note not found");
|
$this->fail(180, "Note not found");
|
||||||
|
}
|
||||||
if($note->isDeleted())
|
|
||||||
|
if ($note->isDeleted()) {
|
||||||
$this->fail(189, "Note is deleted");
|
$this->fail(189, "Note is deleted");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$note->canBeModifiedBy($this->getUser()))
|
if (!$note->canBeModifiedBy($this->getUser())) {
|
||||||
$this->fail(403, "No access");
|
$this->fail(403, "No access");
|
||||||
|
}
|
||||||
|
|
||||||
!empty($title) ? $note->setName($title) : NULL;
|
!empty($title) ? $note->setName($title) : null;
|
||||||
!empty($text) ? $note->setSource($text) : NULL;
|
!empty($text) ? $note->setSource($text) : null;
|
||||||
|
|
||||||
$note->setCached_Content(NULL);
|
$note->setCached_Content(null);
|
||||||
$note->setEdited(time());
|
$note->setEdited(time());
|
||||||
$note->save();
|
$note->save();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(int $user_id, string $note_ids = "", int $offset = 0, int $count = 10, int $sort = 0)
|
public function get(int $user_id, string $note_ids = "", int $offset = 0, int $count = 10, int $sort = 0)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$user = (new UsersRepo)->get($user_id);
|
$user = (new UsersRepo())->get($user_id);
|
||||||
|
|
||||||
if(!$user || $user->isDeleted())
|
if (!$user || $user->isDeleted()) {
|
||||||
$this->fail(15, "Invalid user");
|
$this->fail(15, "Invalid user");
|
||||||
|
}
|
||||||
if(!$user->getPrivacyPermission('notes.read', $this->getUser()))
|
|
||||||
$this->fail(15, "Access denied: this user chose to hide his notes");
|
|
||||||
|
|
||||||
if(!$user->canBeViewedBy($this->getUser()))
|
if (!$user->getPrivacyPermission('notes.read', $this->getUser())) {
|
||||||
|
$this->fail(15, "Access denied: this user chose to hide his notes");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$user->canBeViewedBy($this->getUser())) {
|
||||||
$this->fail(15, "Access denied");
|
$this->fail(15, "Access denied");
|
||||||
|
}
|
||||||
if(empty($note_ids)) {
|
|
||||||
$notes = array_slice(iterator_to_array((new NotesRepo)->getUserNotes($user, 1, $count + $offset, $sort == 0 ? "ASC" : "DESC")), $offset);
|
if (empty($note_ids)) {
|
||||||
|
$notes = array_slice(iterator_to_array((new NotesRepo())->getUserNotes($user, 1, $count + $offset, $sort == 0 ? "ASC" : "DESC")), $offset);
|
||||||
$nodez = (object) [
|
$nodez = (object) [
|
||||||
"count" => (new NotesRepo)->getUserNotesCount((new UsersRepo)->get($user_id)),
|
"count" => (new NotesRepo())->getUserNotesCount((new UsersRepo())->get($user_id)),
|
||||||
"notes" => []
|
"notes" => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach($notes as $note) {
|
foreach ($notes as $note) {
|
||||||
if($note->isDeleted()) continue;
|
if ($note->isDeleted()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$nodez->notes[] = $note->toVkApiStruct();
|
$nodez->notes[] = $note->toVkApiStruct();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$notes = explode(',', $note_ids);
|
$notes = explode(',', $note_ids);
|
||||||
|
|
||||||
foreach($notes as $note)
|
foreach ($notes as $note) {
|
||||||
{
|
|
||||||
$id = explode("_", $note);
|
$id = explode("_", $note);
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
|
|
||||||
$note = (new NotesRepo)->getNoteById((int)$id[0], (int)$id[1]);
|
$note = (new NotesRepo())->getNoteById((int) $id[0], (int) $id[1]);
|
||||||
if($note && !$note->isDeleted()) {
|
if ($note && !$note->isDeleted()) {
|
||||||
$nodez->notes[] = $note->toVkApiStruct();
|
$nodez->notes[] = $note->toVkApiStruct();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,69 +217,79 @@ final class Notes extends VKAPIRequestHandler
|
||||||
return $nodez;
|
return $nodez;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getById(int $note_id, int $owner_id, bool $need_wiki = false)
|
public function getById(int $note_id, int $owner_id, bool $need_wiki = false)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$note = (new NotesRepo)->getNoteById($owner_id, $note_id);
|
$note = (new NotesRepo())->getNoteById($owner_id, $note_id);
|
||||||
|
|
||||||
if(!$note)
|
if (!$note) {
|
||||||
$this->fail(180, "Note not found");
|
$this->fail(180, "Note not found");
|
||||||
|
}
|
||||||
if($note->isDeleted())
|
|
||||||
|
if ($note->isDeleted()) {
|
||||||
$this->fail(189, "Note is deleted");
|
$this->fail(189, "Note is deleted");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$note->getOwner() || $note->getOwner()->isDeleted())
|
if (!$note->getOwner() || $note->getOwner()->isDeleted()) {
|
||||||
$this->fail(177, "Owner does not exists");
|
$this->fail(177, "Owner does not exists");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser()))
|
if (!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser())) {
|
||||||
$this->fail(40, "Access denied: this user chose to hide his notes");
|
$this->fail(40, "Access denied: this user chose to hide his notes");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$note->canBeViewedBy($this->getUser()))
|
if (!$note->canBeViewedBy($this->getUser())) {
|
||||||
$this->fail(15, "Access to note denied");
|
$this->fail(15, "Access to note denied");
|
||||||
|
}
|
||||||
|
|
||||||
return $note->toVkApiStruct();
|
return $note->toVkApiStruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComments(int $note_id, int $owner_id, int $sort = 1, int $offset = 0, int $count = 100)
|
public function getComments(int $note_id, int $owner_id, int $sort = 1, int $offset = 0, int $count = 100)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$note = (new NotesRepo)->getNoteById($owner_id, $note_id);
|
$note = (new NotesRepo())->getNoteById($owner_id, $note_id);
|
||||||
|
|
||||||
if(!$note)
|
if (!$note) {
|
||||||
$this->fail(180, "Note not found");
|
$this->fail(180, "Note not found");
|
||||||
|
}
|
||||||
if($note->isDeleted())
|
|
||||||
|
if ($note->isDeleted()) {
|
||||||
$this->fail(189, "Note is deleted");
|
$this->fail(189, "Note is deleted");
|
||||||
|
}
|
||||||
if(!$note->getOwner())
|
|
||||||
|
if (!$note->getOwner()) {
|
||||||
$this->fail(177, "Owner does not exists");
|
$this->fail(177, "Owner does not exists");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser()))
|
if (!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser())) {
|
||||||
$this->fail(14, "No access");
|
$this->fail(14, "No access");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$note->canBeViewedBy($this->getUser()))
|
if (!$note->canBeViewedBy($this->getUser())) {
|
||||||
$this->fail(15, "Access to note denied");
|
$this->fail(15, "Access to note denied");
|
||||||
|
}
|
||||||
|
|
||||||
$arr = (object) [
|
$arr = (object) [
|
||||||
"count" => $note->getCommentsCount(),
|
"count" => $note->getCommentsCount(),
|
||||||
"comments" => []];
|
"comments" => []];
|
||||||
$comments = array_slice(iterator_to_array($note->getComments(1, $count + $offset)), $offset);
|
$comments = array_slice(iterator_to_array($note->getComments(1, $count + $offset)), $offset);
|
||||||
|
|
||||||
foreach($comments as $comment) {
|
foreach ($comments as $comment) {
|
||||||
$arr->comments[] = $comment->toVkApiStruct($this->getUser(), false, false, $note);
|
$arr->comments[] = $comment->toVkApiStruct($this->getUser(), false, false, $note);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $arr;
|
return $arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFriendsNotes(int $offset = 0, int $count = 0)
|
public function getFriendsNotes(int $offset = 0, int $count = 0)
|
||||||
{
|
{
|
||||||
$this->fail(501, "Not implemented");
|
$this->fail(501, "Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
function restoreComment(int $comment_id = 0, int $owner_id = 0)
|
public function restoreComment(int $comment_id = 0, int $owner_id = 0)
|
||||||
{
|
{
|
||||||
$this->fail(501, "Not implemented");
|
$this->fail(501, "Not implemented");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,62 +1,70 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\Club;
|
use openvk\Web\Models\Entities\Club;
|
||||||
use openvk\Web\Models\Repositories\{Notifications as Notifs, Clubs, Users};
|
use openvk\Web\Models\Repositories\{Notifications as Notifs, Clubs, Users};
|
||||||
|
|
||||||
final class Notifications extends VKAPIRequestHandler
|
final class Notifications extends VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
function get(int $count = 10,
|
public function get(
|
||||||
string $from = "",
|
int $count = 10,
|
||||||
int $offset = 0,
|
string $from = "",
|
||||||
string $start_from = "",
|
int $offset = 0,
|
||||||
string $filters = "",
|
string $start_from = "",
|
||||||
int $start_time = 0,
|
string $filters = "",
|
||||||
int $end_time = 0,
|
int $start_time = 0,
|
||||||
int $archived = 0)
|
int $end_time = 0,
|
||||||
{
|
int $archived = 0
|
||||||
|
) {
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$res = (object)[
|
$res = (object) [
|
||||||
"items" => [],
|
"items" => [],
|
||||||
"profiles" => [],
|
"profiles" => [],
|
||||||
"groups" => [],
|
"groups" => [],
|
||||||
"last_viewed" => $this->getUser()->getNotificationOffset()
|
"last_viewed" => $this->getUser()->getNotificationOffset(),
|
||||||
];
|
];
|
||||||
|
|
||||||
if($count > 100)
|
if ($count > 100) {
|
||||||
$this->fail(125, "Count is too big");
|
$this->fail(125, "Count is too big");
|
||||||
|
}
|
||||||
|
|
||||||
if(!eventdb())
|
if (!eventdb()) {
|
||||||
$this->fail(1289, "EventDB is disabled on this instance");
|
$this->fail(1289, "EventDB is disabled on this instance");
|
||||||
|
}
|
||||||
|
|
||||||
$notifs = array_slice(iterator_to_array((new Notifs)->getNotificationsByUser($this->getUser(), $this->getUser()->getNotificationOffset(), (bool)$archived, 1, $offset + $count)), $offset);
|
$notifs = array_slice(iterator_to_array((new Notifs())->getNotificationsByUser($this->getUser(), $this->getUser()->getNotificationOffset(), (bool) $archived, 1, $offset + $count)), $offset);
|
||||||
$tmpProfiles = [];
|
$tmpProfiles = [];
|
||||||
foreach($notifs as $notif) {
|
foreach ($notifs as $notif) {
|
||||||
$sxModel = $notif->getModel(1);
|
$sxModel = $notif->getModel(1);
|
||||||
|
|
||||||
if(!method_exists($sxModel, "getAvatarUrl"))
|
if (!method_exists($sxModel, "getAvatarUrl")) {
|
||||||
$sxModel = $notif->getModel(0);
|
$sxModel = $notif->getModel(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$tmpProfiles[] = $sxModel instanceof Club ? $sxModel->getId() * -1 : $sxModel->getId();
|
$tmpProfiles[] = $sxModel instanceof Club ? $sxModel->getId() * -1 : $sxModel->getId();
|
||||||
$res->items[] = $notif->toVkApiStruct();
|
$res->items[] = $notif->toVkApiStruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(array_unique($tmpProfiles) as $id) {
|
foreach (array_unique($tmpProfiles) as $id) {
|
||||||
if($id > 0) {
|
if ($id > 0) {
|
||||||
$sxModel = (new Users)->get($id);
|
$sxModel = (new Users())->get($id);
|
||||||
$result = (object)[
|
$result = (object) [
|
||||||
"uid" => $sxModel->getId(),
|
"uid" => $sxModel->getId(),
|
||||||
"first_name" => $sxModel->getFirstName(),
|
"first_name" => $sxModel->getFirstName(),
|
||||||
"last_name" => $sxModel->getLastName(),
|
"last_name" => $sxModel->getLastName(),
|
||||||
"photo" => $sxModel->getAvatarUrl(),
|
"photo" => $sxModel->getAvatarUrl(),
|
||||||
"photo_medium_rec" => $sxModel->getAvatarUrl("tiny"),
|
"photo_medium_rec" => $sxModel->getAvatarUrl("tiny"),
|
||||||
"screen_name" => $sxModel->getShortCode()
|
"screen_name" => $sxModel->getShortCode(),
|
||||||
];
|
];
|
||||||
|
|
||||||
$res->profiles[] = $result;
|
$res->profiles[] = $result;
|
||||||
} else {
|
} else {
|
||||||
$sxModel = (new Clubs)->get(abs($id));
|
$sxModel = (new Clubs())->get(abs($id));
|
||||||
$result = $sxModel->toVkApiStruct($this->getUser());
|
$result = $sxModel->toVkApiStruct($this->getUser());
|
||||||
|
|
||||||
$res->groups[] = $result;
|
$res->groups[] = $result;
|
||||||
|
@ -66,7 +74,7 @@ final class Notifications extends VKAPIRequestHandler
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function markAsViewed()
|
public function markAsViewed()
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
@ -74,7 +82,7 @@ final class Notifications extends VKAPIRequestHandler
|
||||||
try {
|
try {
|
||||||
$this->getUser()->updateNotificationOffset();
|
$this->getUser()->updateNotificationOffset();
|
||||||
$this->getUser()->save();
|
$this->getUser()->save();
|
||||||
} catch(\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use openvk\Web\Models\Repositories\{Users as UsersRepo, Clubs as ClubsRepo, Posts as PostsRepo};
|
use openvk\Web\Models\Repositories\{Users as UsersRepo, Clubs as ClubsRepo, Posts as PostsRepo};
|
||||||
|
|
||||||
final class Ovk extends VKAPIRequestHandler
|
final class Ovk extends VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
function version(): string
|
public function version(): string
|
||||||
{
|
{
|
||||||
return OPENVK_VERSION;
|
return OPENVK_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
function test(): object
|
public function test(): object
|
||||||
{
|
{
|
||||||
return (object) [
|
return (object) [
|
||||||
"authorized" => $this->userAuthorized(),
|
"authorized" => $this->userAuthorized(),
|
||||||
|
@ -17,58 +21,59 @@ final class Ovk extends VKAPIRequestHandler
|
||||||
"version" => VKAPI_DECL_VER,
|
"version" => VKAPI_DECL_VER,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function chickenWings(): string
|
public function chickenWings(): string
|
||||||
{
|
{
|
||||||
return "крылышки";
|
return "крылышки";
|
||||||
}
|
}
|
||||||
|
|
||||||
function aboutInstance(string $fields = "statistics,administrators,popular_groups,links", string $admin_fields = "", string $group_fields = ""): object
|
public function aboutInstance(string $fields = "statistics,administrators,popular_groups,links", string $admin_fields = "", string $group_fields = ""): object
|
||||||
{
|
{
|
||||||
$fields = explode(',', $fields);
|
$fields = explode(',', $fields);
|
||||||
$response = (object) [];
|
$response = (object) [];
|
||||||
|
|
||||||
if(in_array("statistics", $fields)) {
|
if (in_array("statistics", $fields)) {
|
||||||
$usersStats = (new UsersRepo)->getStatistics();
|
$usersStats = (new UsersRepo())->getStatistics();
|
||||||
$clubsCount = (new ClubsRepo)->getCount();
|
$clubsCount = (new ClubsRepo())->getCount();
|
||||||
$postsCount = (new PostsRepo)->getCount();
|
$postsCount = (new PostsRepo())->getCount();
|
||||||
$response->statistics = (object) [
|
$response->statistics = (object) [
|
||||||
"users_count" => $usersStats->all,
|
"users_count" => $usersStats->all,
|
||||||
"online_users_count" => $usersStats->online,
|
"online_users_count" => $usersStats->online,
|
||||||
"active_users_count" => $usersStats->active,
|
"active_users_count" => $usersStats->active,
|
||||||
"groups_count" => $clubsCount,
|
"groups_count" => $clubsCount,
|
||||||
"wall_posts_count" => $postsCount
|
"wall_posts_count" => $postsCount,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(in_array("administrators", $fields)) {
|
if (in_array("administrators", $fields)) {
|
||||||
$admins = iterator_to_array((new UsersRepo)->getInstanceAdmins());
|
$admins = iterator_to_array((new UsersRepo())->getInstanceAdmins());
|
||||||
$adminsResponse = (new Users($this->getUser()))->get(implode(',', array_map(function($admin) {
|
$adminsResponse = (new Users($this->getUser()))->get(implode(',', array_map(function ($admin) {
|
||||||
return $admin->getId();
|
return $admin->getId();
|
||||||
}, $admins)), $admin_fields, 0, sizeof($admins));
|
}, $admins)), $admin_fields, 0, sizeof($admins));
|
||||||
$response->administrators = (object) [
|
$response->administrators = (object) [
|
||||||
"count" => sizeof($admins),
|
"count" => sizeof($admins),
|
||||||
"items" => $adminsResponse
|
"items" => $adminsResponse,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(in_array("popular_groups", $fields)) {
|
if (in_array("popular_groups", $fields)) {
|
||||||
$popularClubs = iterator_to_array((new ClubsRepo)->getPopularClubs());
|
$popularClubs = iterator_to_array((new ClubsRepo())->getPopularClubs());
|
||||||
$clubsResponse = (new Groups($this->getUser()))->getById(implode(',', array_map(function($entry) {
|
$clubsResponse = (new Groups($this->getUser()))->getById(implode(',', array_map(function ($entry) {
|
||||||
return $entry->club->getId();
|
return $entry->club->getId();
|
||||||
}, $popularClubs)), "", "members_count, " . $group_fields);
|
}, $popularClubs)), "", "members_count, " . $group_fields);
|
||||||
|
|
||||||
$response->popular_groups = (object) [
|
$response->popular_groups = (object) [
|
||||||
"count" => sizeof($popularClubs),
|
"count" => sizeof($popularClubs),
|
||||||
"items" => $clubsResponse
|
"items" => $clubsResponse,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(in_array("links", $fields))
|
if (in_array("links", $fields)) {
|
||||||
$response->links = (object) [
|
$response->links = (object) [
|
||||||
"count" => sizeof(OPENVK_ROOT_CONF['openvk']['preferences']['about']['links']),
|
"count" => sizeof(OPENVK_ROOT_CONF['openvk']['preferences']['about']['links']),
|
||||||
"items" => is_null(OPENVK_ROOT_CONF['openvk']['preferences']['about']['links']) ? [] : OPENVK_ROOT_CONF['openvk']['preferences']['about']['links']
|
"items" => is_null(OPENVK_ROOT_CONF['openvk']['preferences']['about']['links']) ? [] : OPENVK_ROOT_CONF['openvk']['preferences']['about']['links'],
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +1,49 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use openvk\Web\Models\Repositories\Applications;
|
use openvk\Web\Models\Repositories\Applications;
|
||||||
|
|
||||||
final class Pay extends VKAPIRequestHandler
|
final class Pay extends VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
function getIdByMarketingId(string $marketing_id): int
|
public function getIdByMarketingId(string $marketing_id): int
|
||||||
{
|
{
|
||||||
[$hexId, $signature] = explode("_", $marketing_id);
|
[$hexId, $signature] = explode("_", $marketing_id);
|
||||||
try {
|
try {
|
||||||
$key = CHANDLER_ROOT_CONF["security"]["secret"];
|
$key = CHANDLER_ROOT_CONF["security"]["secret"];
|
||||||
if(sodium_memcmp(base64_decode($signature), hash_hmac("sha512/224", $hexId, $key, true)) == -1)
|
if (sodium_memcmp(base64_decode($signature), hash_hmac("sha512/224", $hexId, $key, true)) == -1) {
|
||||||
$this->fail(4, "Invalid marketing id");
|
$this->fail(4, "Invalid marketing id");
|
||||||
|
}
|
||||||
} catch (\SodiumException $e) {
|
} catch (\SodiumException $e) {
|
||||||
$this->fail(4, "Invalid marketing id");
|
$this->fail(4, "Invalid marketing id");
|
||||||
}
|
}
|
||||||
|
|
||||||
return hexdec($hexId);
|
return hexdec($hexId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyOrder(int $app_id, float $amount, string $signature): bool
|
public function verifyOrder(int $app_id, float $amount, string $signature): bool
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$app = (new Applications())->get($app_id);
|
$app = (new Applications())->get($app_id);
|
||||||
if(!$app)
|
if (!$app) {
|
||||||
$this->fail(26, "No app found with this id");
|
$this->fail(26, "No app found with this id");
|
||||||
else if($app->getOwner()->getId() != $this->getUser()->getId())
|
} elseif ($app->getOwner()->getId() != $this->getUser()->getId()) {
|
||||||
$this->fail(15, "Access error");
|
$this->fail(15, "Access error");
|
||||||
|
}
|
||||||
|
|
||||||
[$time, $signature] = explode(",", $signature);
|
[$time, $signature] = explode(",", $signature);
|
||||||
try {
|
try {
|
||||||
$key = CHANDLER_ROOT_CONF["security"]["secret"];
|
$key = CHANDLER_ROOT_CONF["security"]["secret"];
|
||||||
if(sodium_memcmp($signature, hash_hmac("whirlpool", "$app_id:$amount:$time", $key)) == -1)
|
if (sodium_memcmp($signature, hash_hmac("whirlpool", "$app_id:$amount:$time", $key)) == -1) {
|
||||||
$this->fail(4, "Invalid order");
|
$this->fail(4, "Invalid order");
|
||||||
|
}
|
||||||
} catch (\SodiumException $e) {
|
} catch (\SodiumException $e) {
|
||||||
$this->fail(4, "Invalid order");
|
$this->fail(4, "Invalid order");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use Nette\InvalidStateException;
|
use Nette\InvalidStateException;
|
||||||
|
@ -33,31 +36,34 @@ final class Photos extends VKAPIRequestHandler
|
||||||
return ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/upload/photo/$uploadHash?$uploadInfo";
|
return ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/upload/photo/$uploadHash?$uploadInfo";
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getImagePath(string $photo, string $hash, ?string& $up = NULL, ?string& $group = NULL): string
|
private function getImagePath(string $photo, string $hash, ?string& $up = null, ?string& $group = null): string
|
||||||
{
|
{
|
||||||
$secret = CHANDLER_ROOT_CONF["security"]["secret"];
|
$secret = CHANDLER_ROOT_CONF["security"]["secret"];
|
||||||
if(!hash_equals(hash_hmac("sha3-224", $photo, $secret), $hash))
|
if (!hash_equals(hash_hmac("sha3-224", $photo, $secret), $hash)) {
|
||||||
$this->fail(121, "Incorrect hash");
|
$this->fail(121, "Incorrect hash");
|
||||||
|
}
|
||||||
|
|
||||||
[$up, $image, $group] = explode("|", $photo);
|
[$up, $image, $group] = explode("|", $photo);
|
||||||
|
|
||||||
$imagePath = __DIR__ . "/../../tmp/api-storage/photos/$up" . "_$image.oct";
|
$imagePath = __DIR__ . "/../../tmp/api-storage/photos/$up" . "_$image.oct";
|
||||||
if(!file_exists($imagePath))
|
if (!file_exists($imagePath)) {
|
||||||
$this->fail(10, "Invalid image");
|
$this->fail(10, "Invalid image");
|
||||||
|
}
|
||||||
|
|
||||||
return $imagePath;
|
return $imagePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOwnerPhotoUploadServer(int $owner_id = 0): object
|
public function getOwnerPhotoUploadServer(int $owner_id = 0): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
if($owner_id < 0) {
|
if ($owner_id < 0) {
|
||||||
$club = (new Clubs)->get(abs($owner_id));
|
$club = (new Clubs())->get(abs($owner_id));
|
||||||
if(!$club)
|
if (!$club) {
|
||||||
$this->fail(0404, "Club not found");
|
$this->fail(0o404, "Club not found");
|
||||||
else if(!$club->canBeModifiedBy($this->getUser()))
|
} elseif (!$club->canBeModifiedBy($this->getUser())) {
|
||||||
$this->fail(200, "Access: Club can't be 'written' by user");
|
$this->fail(200, "Access: Club can't be 'written' by user");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
|
@ -65,19 +71,19 @@ final class Photos extends VKAPIRequestHandler
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveOwnerPhoto(string $photo, string $hash): object
|
public function saveOwnerPhoto(string $photo, string $hash): object
|
||||||
{
|
{
|
||||||
$imagePath = $this->getImagePath($photo, $hash, $uploader, $group);
|
$imagePath = $this->getImagePath($photo, $hash, $uploader, $group);
|
||||||
if($group == 0) {
|
if ($group == 0) {
|
||||||
$user = (new \openvk\Web\Models\Repositories\Users)->get((int) $uploader);
|
$user = (new \openvk\Web\Models\Repositories\Users())->get((int) $uploader);
|
||||||
$album = (new Albums)->getUserAvatarAlbum($user);
|
$album = (new Albums())->getUserAvatarAlbum($user);
|
||||||
} else {
|
} else {
|
||||||
$club = (new Clubs)->get((int) $group);
|
$club = (new Clubs())->get((int) $group);
|
||||||
$album = (new Albums)->getClubAvatarAlbum($club);
|
$album = (new Albums())->getClubAvatarAlbum($club);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$avatar = new Photo;
|
$avatar = new Photo();
|
||||||
$avatar->setOwner((int) $uploader);
|
$avatar->setOwner((int) $uploader);
|
||||||
$avatar->setDescription("Profile photo");
|
$avatar->setDescription("Profile photo");
|
||||||
$avatar->setCreated(time());
|
$avatar->setCreated(time());
|
||||||
|
@ -88,30 +94,31 @@ final class Photos extends VKAPIRequestHandler
|
||||||
$avatar->save();
|
$avatar->save();
|
||||||
$album->addPhoto($avatar);
|
$album->addPhoto($avatar);
|
||||||
unlink($imagePath);
|
unlink($imagePath);
|
||||||
} catch(ImageException | InvalidStateException $e) {
|
} catch (ImageException | InvalidStateException $e) {
|
||||||
unlink($imagePath);
|
unlink($imagePath);
|
||||||
$this->fail(129, "Invalid image file");
|
$this->fail(129, "Invalid image file");
|
||||||
}
|
}
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
"photo_hash" => NULL,
|
"photo_hash" => null,
|
||||||
"photo_src" => $avatar->getURL(),
|
"photo_src" => $avatar->getURL(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getWallUploadServer(?int $group_id = NULL): object
|
public function getWallUploadServer(?int $group_id = null): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$album = NULL;
|
$album = null;
|
||||||
if(!is_null($group_id)) {
|
if (!is_null($group_id)) {
|
||||||
$club = (new Clubs)->get(abs($group_id));
|
$club = (new Clubs())->get(abs($group_id));
|
||||||
if(!$club)
|
if (!$club) {
|
||||||
$this->fail(0404, "Club not found");
|
$this->fail(0o404, "Club not found");
|
||||||
else if(!$club->canBeModifiedBy($this->getUser()))
|
} elseif (!$club->canBeModifiedBy($this->getUser())) {
|
||||||
$this->fail(200, "Access: Club can't be 'written' by user");
|
$this->fail(200, "Access: Club can't be 'written' by user");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$album = (new Albums)->getUserWallAlbum($this->getUser());
|
$album = (new Albums())->getUserWallAlbum($this->getUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
|
@ -121,20 +128,21 @@ final class Photos extends VKAPIRequestHandler
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveWallPhoto(string $photo, string $hash, int $group_id = 0, ?string $caption = NULL): array
|
public function saveWallPhoto(string $photo, string $hash, int $group_id = 0, ?string $caption = null): array
|
||||||
{
|
{
|
||||||
$imagePath = $this->getImagePath($photo, $hash, $uploader, $group);
|
$imagePath = $this->getImagePath($photo, $hash, $uploader, $group);
|
||||||
if($group_id != $group)
|
if ($group_id != $group) {
|
||||||
$this->fail(8, "group_id doesn't match");
|
$this->fail(8, "group_id doesn't match");
|
||||||
|
}
|
||||||
|
|
||||||
$album = NULL;
|
$album = null;
|
||||||
if($group_id != 0) {
|
if ($group_id != 0) {
|
||||||
$uploader = (new \openvk\Web\Models\Repositories\Users)->get((int) $uploader);
|
$uploader = (new \openvk\Web\Models\Repositories\Users())->get((int) $uploader);
|
||||||
$album = (new Albums)->getUserWallAlbum($uploader);
|
$album = (new Albums())->getUserWallAlbum($uploader);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$photo = new Photo;
|
$photo = new Photo();
|
||||||
$photo->setOwner((int) $uploader);
|
$photo->setOwner((int) $uploader);
|
||||||
$photo->setCreated(time());
|
$photo->setCreated(time());
|
||||||
$photo->setFile([
|
$photo->setFile([
|
||||||
|
@ -142,25 +150,27 @@ final class Photos extends VKAPIRequestHandler
|
||||||
"error" => 0,
|
"error" => 0,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (!is_null($caption))
|
if (!is_null($caption)) {
|
||||||
$photo->setDescription($caption);
|
$photo->setDescription($caption);
|
||||||
|
}
|
||||||
|
|
||||||
$photo->save();
|
$photo->save();
|
||||||
unlink($imagePath);
|
unlink($imagePath);
|
||||||
} catch(ImageException | InvalidStateException $e) {
|
} catch (ImageException | InvalidStateException $e) {
|
||||||
unlink($imagePath);
|
unlink($imagePath);
|
||||||
$this->fail(129, "Invalid image file");
|
$this->fail(129, "Invalid image file");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!is_null($album))
|
if (!is_null($album)) {
|
||||||
$album->addPhoto($photo);
|
$album->addPhoto($photo);
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
$photo->toVkApiStruct(),
|
$photo->toVkApiStruct(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUploadServer(?int $album_id = NULL): object
|
public function getUploadServer(?int $album_id = null): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
|
@ -172,34 +182,37 @@ final class Photos extends VKAPIRequestHandler
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function save(string $photos_list, string $hash, int $album_id = 0, ?string $caption = NULL): object
|
public function save(string $photos_list, string $hash, int $album_id = 0, ?string $caption = null): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$secret = CHANDLER_ROOT_CONF["security"]["secret"];
|
$secret = CHANDLER_ROOT_CONF["security"]["secret"];
|
||||||
if(!hash_equals(hash_hmac("sha3-224", $photos_list, $secret), $hash))
|
if (!hash_equals(hash_hmac("sha3-224", $photos_list, $secret), $hash)) {
|
||||||
$this->fail(121, "Incorrect hash");
|
$this->fail(121, "Incorrect hash");
|
||||||
|
}
|
||||||
|
|
||||||
$album = NULL;
|
$album = null;
|
||||||
if($album_id != 0) {
|
if ($album_id != 0) {
|
||||||
$album_ = (new Albums)->get($album_id);
|
$album_ = (new Albums())->get($album_id);
|
||||||
if(!$album_)
|
if (!$album_) {
|
||||||
$this->fail(0404, "Invalid album");
|
$this->fail(0o404, "Invalid album");
|
||||||
else if(!$album_->canBeModifiedBy($this->getUser()))
|
} elseif (!$album_->canBeModifiedBy($this->getUser())) {
|
||||||
$this->fail(15, "Access: Album can't be 'written' by user");
|
$this->fail(15, "Access: Album can't be 'written' by user");
|
||||||
|
}
|
||||||
|
|
||||||
$album = $album_;
|
$album = $album_;
|
||||||
}
|
}
|
||||||
|
|
||||||
$pList = json_decode($photos_list);
|
$pList = json_decode($photos_list);
|
||||||
$imagePaths = [];
|
$imagePaths = [];
|
||||||
foreach($pList as $pDesc)
|
foreach ($pList as $pDesc) {
|
||||||
$imagePaths[] = __DIR__ . "/../../tmp/api-storage/photos/$pDesc->keyholder" . "_$pDesc->resource.oct";
|
$imagePaths[] = __DIR__ . "/../../tmp/api-storage/photos/$pDesc->keyholder" . "_$pDesc->resource.oct";
|
||||||
|
}
|
||||||
|
|
||||||
$images = [];
|
$images = [];
|
||||||
try {
|
try {
|
||||||
foreach($imagePaths as $imagePath) {
|
foreach ($imagePaths as $imagePath) {
|
||||||
$photo = new Photo;
|
$photo = new Photo();
|
||||||
$photo->setOwner($this->getUser()->getId());
|
$photo->setOwner($this->getUser()->getId());
|
||||||
$photo->setCreated(time());
|
$photo->setCreated(time());
|
||||||
$photo->setFile([
|
$photo->setFile([
|
||||||
|
@ -207,20 +220,23 @@ final class Photos extends VKAPIRequestHandler
|
||||||
"error" => 0,
|
"error" => 0,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (!is_null($caption))
|
if (!is_null($caption)) {
|
||||||
$photo->setDescription($caption);
|
$photo->setDescription($caption);
|
||||||
|
}
|
||||||
|
|
||||||
$photo->save();
|
$photo->save();
|
||||||
unlink($imagePath);
|
unlink($imagePath);
|
||||||
|
|
||||||
if(!is_null($album))
|
if (!is_null($album)) {
|
||||||
$album->addPhoto($photo);
|
$album->addPhoto($photo);
|
||||||
|
}
|
||||||
|
|
||||||
$images[] = $photo->toVkApiStruct();
|
$images[] = $photo->toVkApiStruct();
|
||||||
}
|
}
|
||||||
} catch(ImageException | InvalidStateException $e) {
|
} catch (ImageException | InvalidStateException $e) {
|
||||||
foreach($imagePaths as $imagePath)
|
foreach ($imagePaths as $imagePath) {
|
||||||
unlink($imagePath);
|
unlink($imagePath);
|
||||||
|
}
|
||||||
|
|
||||||
$this->fail(129, "Invalid image file");
|
$this->fail(129, "Invalid image file");
|
||||||
}
|
}
|
||||||
|
@ -231,20 +247,20 @@ final class Photos extends VKAPIRequestHandler
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function createAlbum(string $title, int $group_id = 0, string $description = "", int $privacy = 0)
|
public function createAlbum(string $title, int $group_id = 0, string $description = "", int $privacy = 0)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
if($group_id != 0) {
|
if ($group_id != 0) {
|
||||||
$club = (new Clubs)->get((int) $group_id);
|
$club = (new Clubs())->get((int) $group_id);
|
||||||
|
|
||||||
if(!$club || !$club->canBeModifiedBy($this->getUser())) {
|
if (!$club || !$club->canBeModifiedBy($this->getUser())) {
|
||||||
$this->fail(20, "Invalid club");
|
$this->fail(20, "Invalid club");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$album = new Album;
|
$album = new Album();
|
||||||
$album->setOwner(isset($club) ? $club->getId() * -1 : $this->getUser()->getId());
|
$album->setOwner(isset($club) ? $club->getId() * -1 : $this->getUser()->getId());
|
||||||
$album->setName($title);
|
$album->setName($title);
|
||||||
$album->setDescription($description);
|
$album->setDescription($description);
|
||||||
|
@ -254,26 +270,26 @@ final class Photos extends VKAPIRequestHandler
|
||||||
return $album->toVkApiStruct($this->getUser());
|
return $album->toVkApiStruct($this->getUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
function editAlbum(int $album_id, int $owner_id, string $title, string $description = "", int $privacy = 0)
|
public function editAlbum(int $album_id, int $owner_id, string $title, string $description = "", int $privacy = 0)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$album = (new Albums)->getAlbumByOwnerAndId($owner_id, $album_id);
|
$album = (new Albums())->getAlbumByOwnerAndId($owner_id, $album_id);
|
||||||
|
|
||||||
if(!$album || $album->isDeleted()) {
|
if (!$album || $album->isDeleted()) {
|
||||||
$this->fail(2, "Invalid album");
|
$this->fail(2, "Invalid album");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(empty($title)) {
|
if (empty($title)) {
|
||||||
$this->fail(25, "Title is empty");
|
$this->fail(25, "Title is empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
if($album->isCreatedBySystem()) {
|
if ($album->isCreatedBySystem()) {
|
||||||
$this->fail(40, "You can't change system album");
|
$this->fail(40, "You can't change system album");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$album->canBeModifiedBy($this->getUser())) {
|
if (!$album->canBeModifiedBy($this->getUser())) {
|
||||||
$this->fail(2, "Access to album denied");
|
$this->fail(2, "Access to album denied");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,50 +301,55 @@ final class Photos extends VKAPIRequestHandler
|
||||||
return $album->toVkApiStruct($this->getUser());
|
return $album->toVkApiStruct($this->getUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAlbums(int $owner_id, string $album_ids = "", int $offset = 0, int $count = 100, bool $need_system = true, bool $need_covers = true, bool $photo_sizes = false)
|
public function getAlbums(int $owner_id, string $album_ids = "", int $offset = 0, int $count = 100, bool $need_system = true, bool $need_covers = true, bool $photo_sizes = false)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$res = [];
|
$res = [];
|
||||||
|
|
||||||
if(empty($album_ids)) {
|
if (empty($album_ids)) {
|
||||||
if($owner_id > 0) {
|
if ($owner_id > 0) {
|
||||||
$user = (new UsersRepo)->get($owner_id);
|
$user = (new UsersRepo())->get($owner_id);
|
||||||
|
|
||||||
$res = [
|
$res = [
|
||||||
"count" => (new Albums)->getUserAlbumsCount($user),
|
"count" => (new Albums())->getUserAlbumsCount($user),
|
||||||
"items" => []
|
"items" => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
if(!$user || $user->isDeleted())
|
if (!$user || $user->isDeleted()) {
|
||||||
$this->fail(2, "Invalid user");
|
$this->fail(2, "Invalid user");
|
||||||
|
}
|
||||||
if(!$user->getPrivacyPermission('photos.read', $this->getUser()))
|
|
||||||
|
if (!$user->getPrivacyPermission('photos.read', $this->getUser())) {
|
||||||
$this->fail(21, "This user chose to hide his albums.");
|
$this->fail(21, "This user chose to hide his albums.");
|
||||||
|
}
|
||||||
|
|
||||||
$albums = array_slice(iterator_to_array((new Albums)->getUserAlbums($user, 1, $count + $offset)), $offset);
|
$albums = array_slice(iterator_to_array((new Albums())->getUserAlbums($user, 1, $count + $offset)), $offset);
|
||||||
|
|
||||||
foreach($albums as $album) {
|
foreach ($albums as $album) {
|
||||||
if(!$need_system && $album->isCreatedBySystem()) continue;
|
if (!$need_system && $album->isCreatedBySystem()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$res["items"][] = $album->toVkApiStruct($this->getUser(), $need_covers, $photo_sizes);
|
$res["items"][] = $album->toVkApiStruct($this->getUser(), $need_covers, $photo_sizes);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
$club = (new Clubs())->get($owner_id * -1);
|
||||||
else {
|
|
||||||
$club = (new Clubs)->get($owner_id * -1);
|
|
||||||
|
|
||||||
$res = [
|
$res = [
|
||||||
"count" => (new Albums)->getClubAlbumsCount($club),
|
"count" => (new Albums())->getClubAlbumsCount($club),
|
||||||
"items" => []
|
"items" => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
if(!$club)
|
if (!$club) {
|
||||||
$this->fail(2, "Invalid club");
|
$this->fail(2, "Invalid club");
|
||||||
|
}
|
||||||
$albums = array_slice(iterator_to_array((new Albums)->getClubAlbums($club, 1, $count + $offset)), $offset);
|
|
||||||
|
|
||||||
foreach($albums as $album) {
|
$albums = array_slice(iterator_to_array((new Albums())->getClubAlbums($club, 1, $count + $offset)), $offset);
|
||||||
if(!$need_system && $album->isCreatedBySystem()) continue;
|
|
||||||
|
foreach ($albums as $album) {
|
||||||
|
if (!$need_system && $album->isCreatedBySystem()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$res["items"][] = $album->toVkApiStruct($this->getUser(), $need_covers, $photo_sizes);
|
$res["items"][] = $album->toVkApiStruct($this->getUser(), $need_covers, $photo_sizes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -338,16 +359,17 @@ final class Photos extends VKAPIRequestHandler
|
||||||
|
|
||||||
$res = [
|
$res = [
|
||||||
"count" => sizeof($albums),
|
"count" => sizeof($albums),
|
||||||
"items" => []
|
"items" => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach($albums as $album)
|
foreach ($albums as $album) {
|
||||||
{
|
|
||||||
$id = explode("_", $album);
|
$id = explode("_", $album);
|
||||||
|
|
||||||
$album = (new Albums)->getAlbumByOwnerAndId((int)$id[0], (int)$id[1]);
|
$album = (new Albums())->getAlbumByOwnerAndId((int) $id[0], (int) $id[1]);
|
||||||
if($album && !$album->isDeleted()) {
|
if ($album && !$album->isDeleted()) {
|
||||||
if(!$need_system && $album->isCreatedBySystem()) continue;
|
if (!$need_system && $album->isCreatedBySystem()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$res["items"][] = $album->toVkApiStruct($this->getUser(), $need_covers, $photo_sizes);
|
$res["items"][] = $album->toVkApiStruct($this->getUser(), $need_covers, $photo_sizes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -356,50 +378,55 @@ final class Photos extends VKAPIRequestHandler
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAlbumsCount(int $user_id = 0, int $group_id = 0)
|
public function getAlbumsCount(int $user_id = 0, int $group_id = 0)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
if($user_id == 0 && $group_id == 0 || $user_id > 0 && $group_id > 0)
|
if ($user_id == 0 && $group_id == 0 || $user_id > 0 && $group_id > 0) {
|
||||||
$this->fail(21, "Select user_id or group_id");
|
$this->fail(21, "Select user_id or group_id");
|
||||||
|
|
||||||
if($user_id > 0) {
|
|
||||||
$us = (new UsersRepo)->get($user_id);
|
|
||||||
if(!$us || $us->isDeleted())
|
|
||||||
$this->fail(21, "Invalid user");
|
|
||||||
|
|
||||||
if(!$us->getPrivacyPermission('photos.read', $this->getUser()))
|
|
||||||
$this->fail(21, "This user chose to hide his albums.");
|
|
||||||
|
|
||||||
return (new Albums)->getUserAlbumsCount($us);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if($group_id > 0) {
|
if ($user_id > 0) {
|
||||||
$cl = (new Clubs)->get($group_id);
|
$us = (new UsersRepo())->get($user_id);
|
||||||
if(!$cl) {
|
if (!$us || $us->isDeleted()) {
|
||||||
|
$this->fail(21, "Invalid user");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$us->getPrivacyPermission('photos.read', $this->getUser())) {
|
||||||
|
$this->fail(21, "This user chose to hide his albums.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (new Albums())->getUserAlbumsCount($us);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($group_id > 0) {
|
||||||
|
$cl = (new Clubs())->get($group_id);
|
||||||
|
if (!$cl) {
|
||||||
$this->fail(21, "Invalid club");
|
$this->fail(21, "Invalid club");
|
||||||
}
|
}
|
||||||
|
|
||||||
return (new Albums)->getClubAlbumsCount($cl);
|
return (new Albums())->getClubAlbumsCount($cl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getById(string $photos, bool $extended = false, bool $photo_sizes = false)
|
public function getById(string $photos, bool $extended = false, bool $photo_sizes = false)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$phts = explode(",", $photos);
|
$phts = explode(",", $photos);
|
||||||
$res = [];
|
$res = [];
|
||||||
|
|
||||||
foreach($phts as $phota) {
|
foreach ($phts as $phota) {
|
||||||
$ph = explode("_", $phota);
|
$ph = explode("_", $phota);
|
||||||
$photo = (new PhotosRepo)->getByOwnerAndVID((int)$ph[0], (int)$ph[1]);
|
$photo = (new PhotosRepo())->getByOwnerAndVID((int) $ph[0], (int) $ph[1]);
|
||||||
|
|
||||||
if(!$photo || $photo->isDeleted())
|
|
||||||
$this->fail(21, "Invalid photo");
|
|
||||||
|
|
||||||
if(!$photo->canBeViewedBy($this->getUser()))
|
if (!$photo || $photo->isDeleted()) {
|
||||||
|
$this->fail(21, "Invalid photo");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$photo->canBeViewedBy($this->getUser())) {
|
||||||
$this->fail(15, "Access denied");
|
$this->fail(15, "Access denied");
|
||||||
|
}
|
||||||
|
|
||||||
$res[] = $photo->toVkApiStruct($photo_sizes, $extended);
|
$res[] = $photo->toVkApiStruct($photo_sizes, $extended);
|
||||||
}
|
}
|
||||||
|
@ -407,26 +434,30 @@ final class Photos extends VKAPIRequestHandler
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(int $owner_id, int $album_id, string $photo_ids = "", bool $extended = false, bool $photo_sizes = false, int $offset = 0, int $count = 10)
|
public function get(int $owner_id, int $album_id, string $photo_ids = "", bool $extended = false, bool $photo_sizes = false, int $offset = 0, int $count = 10)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$res = [];
|
$res = [];
|
||||||
|
|
||||||
if(empty($photo_ids)) {
|
if (empty($photo_ids)) {
|
||||||
$album = (new Albums)->getAlbumByOwnerAndId($owner_id, $album_id);
|
$album = (new Albums())->getAlbumByOwnerAndId($owner_id, $album_id);
|
||||||
|
|
||||||
if(!$album || $album->isDeleted())
|
if (!$album || $album->isDeleted()) {
|
||||||
$this->fail(21, "Invalid album");
|
$this->fail(21, "Invalid album");
|
||||||
|
}
|
||||||
if(!$album->canBeViewedBy($this->getUser()))
|
|
||||||
|
if (!$album->canBeViewedBy($this->getUser())) {
|
||||||
$this->fail(15, "Access denied");
|
$this->fail(15, "Access denied");
|
||||||
|
}
|
||||||
|
|
||||||
$photos = array_slice(iterator_to_array($album->getPhotos(1, $count + $offset)), $offset);
|
$photos = array_slice(iterator_to_array($album->getPhotos(1, $count + $offset)), $offset);
|
||||||
$res["count"] = $album->size();
|
$res["count"] = $album->size();
|
||||||
|
|
||||||
foreach($photos as $photo) {
|
foreach ($photos as $photo) {
|
||||||
if(!$photo || $photo->isDeleted()) continue;
|
if (!$photo || $photo->isDeleted()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$res["items"][] = $photo->toVkApiStruct($photo_sizes, $extended);
|
$res["items"][] = $photo->toVkApiStruct($photo_sizes, $extended);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,14 +466,14 @@ final class Photos extends VKAPIRequestHandler
|
||||||
|
|
||||||
$res = [
|
$res = [
|
||||||
"count" => sizeof($photos),
|
"count" => sizeof($photos),
|
||||||
"items" => []
|
"items" => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach($photos as $photo) {
|
foreach ($photos as $photo) {
|
||||||
$id = explode("_", $photo);
|
$id = explode("_", $photo);
|
||||||
|
|
||||||
$phot = (new PhotosRepo)->getByOwnerAndVID((int)$id[0], (int)$id[1]);
|
$phot = (new PhotosRepo())->getByOwnerAndVID((int) $id[0], (int) $id[1]);
|
||||||
if($phot && !$phot->isDeleted() && $phot->canBeViewedBy($this->getUser())) {
|
if ($phot && !$phot->isDeleted() && $phot->canBeViewedBy($this->getUser())) {
|
||||||
$res["items"][] = $phot->toVkApiStruct($photo_sizes, $extended);
|
$res["items"][] = $phot->toVkApiStruct($photo_sizes, $extended);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -451,38 +482,42 @@ final class Photos extends VKAPIRequestHandler
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteAlbum(int $album_id, int $group_id = 0)
|
public function deleteAlbum(int $album_id, int $group_id = 0)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$album = (new Albums)->get($album_id);
|
$album = (new Albums())->get($album_id);
|
||||||
|
|
||||||
if(!$album || $album->canBeModifiedBy($this->getUser()))
|
if (!$album || $album->canBeModifiedBy($this->getUser())) {
|
||||||
$this->fail(21, "Invalid album");
|
$this->fail(21, "Invalid album");
|
||||||
|
}
|
||||||
|
|
||||||
if($album->isDeleted())
|
if ($album->isDeleted()) {
|
||||||
$this->fail(22, "Album already deleted");
|
$this->fail(22, "Album already deleted");
|
||||||
|
}
|
||||||
|
|
||||||
$album->delete();
|
$album->delete();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function edit(int $owner_id, int $photo_id, string $caption = "")
|
public function edit(int $owner_id, int $photo_id, string $caption = "")
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id);
|
$photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $photo_id);
|
||||||
|
|
||||||
if(!$photo)
|
if (!$photo) {
|
||||||
$this->fail(21, "Invalid photo");
|
$this->fail(21, "Invalid photo");
|
||||||
|
}
|
||||||
|
|
||||||
if($photo->isDeleted())
|
if ($photo->isDeleted()) {
|
||||||
$this->fail(21, "Photo is deleted");
|
$this->fail(21, "Photo is deleted");
|
||||||
|
}
|
||||||
|
|
||||||
if(!empty($caption)) {
|
if (!empty($caption)) {
|
||||||
$photo->setDescription($caption);
|
$photo->setDescription($caption);
|
||||||
$photo->save();
|
$photo->save();
|
||||||
}
|
}
|
||||||
|
@ -490,41 +525,46 @@ final class Photos extends VKAPIRequestHandler
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete(int $owner_id, int $photo_id, string $photos = "")
|
public function delete(int $owner_id, int $photo_id, string $photos = "")
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
if(empty($photos)) {
|
if (empty($photos)) {
|
||||||
$photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id);
|
$photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $photo_id);
|
||||||
|
|
||||||
if($this->getUser()->getId() !== $photo->getOwner()->getId())
|
if ($this->getUser()->getId() !== $photo->getOwner()->getId()) {
|
||||||
$this->fail(21, "You can't delete another's photo");
|
$this->fail(21, "You can't delete another's photo");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$photo)
|
if (!$photo) {
|
||||||
$this->fail(21, "Invalid photo");
|
$this->fail(21, "Invalid photo");
|
||||||
|
}
|
||||||
|
|
||||||
if($photo->isDeleted())
|
if ($photo->isDeleted()) {
|
||||||
$this->fail(21, "Photo is already deleted");
|
$this->fail(21, "Photo is already deleted");
|
||||||
|
}
|
||||||
|
|
||||||
$photo->delete();
|
$photo->delete();
|
||||||
} else {
|
} else {
|
||||||
$photozs = explode(',', $photos);
|
$photozs = explode(',', $photos);
|
||||||
|
|
||||||
foreach($photozs as $photo)
|
foreach ($photozs as $photo) {
|
||||||
{
|
|
||||||
$id = explode("_", $photo);
|
$id = explode("_", $photo);
|
||||||
|
|
||||||
$phot = (new PhotosRepo)->getByOwnerAndVID((int)$id[0], (int)$id[1]);
|
|
||||||
|
|
||||||
if($this->getUser()->getId() !== $phot->getOwner()->getId())
|
$phot = (new PhotosRepo())->getByOwnerAndVID((int) $id[0], (int) $id[1]);
|
||||||
|
|
||||||
|
if ($this->getUser()->getId() !== $phot->getOwner()->getId()) {
|
||||||
$this->fail(21, "You can't delete another's photo");
|
$this->fail(21, "You can't delete another's photo");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$phot)
|
if (!$phot) {
|
||||||
$this->fail(21, "Invalid photo");
|
$this->fail(21, "Invalid photo");
|
||||||
|
}
|
||||||
if($phot->isDeleted())
|
|
||||||
|
if ($phot->isDeleted()) {
|
||||||
$this->fail(21, "Photo already deleted");
|
$this->fail(21, "Photo already deleted");
|
||||||
|
}
|
||||||
|
|
||||||
$phot->delete();
|
$phot->delete();
|
||||||
}
|
}
|
||||||
|
@ -533,45 +573,50 @@ final class Photos extends VKAPIRequestHandler
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAllComments(int $owner_id, int $album_id, bool $need_likes = false, int $offset = 0, int $count = 100)
|
public function getAllComments(int $owner_id, int $album_id, bool $need_likes = false, int $offset = 0, int $count = 100)
|
||||||
{
|
{
|
||||||
$this->fail(501, "Not implemented");
|
$this->fail(501, "Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteComment(int $comment_id, int $owner_id = 0)
|
public function deleteComment(int $comment_id, int $owner_id = 0)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$comment = (new CommentsRepo)->get($comment_id);
|
$comment = (new CommentsRepo())->get($comment_id);
|
||||||
if(!$comment)
|
if (!$comment) {
|
||||||
$this->fail(21, "Invalid comment");
|
$this->fail(21, "Invalid comment");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$comment->canBeModifiedBy($this->getUser()))
|
if (!$comment->canBeModifiedBy($this->getUser())) {
|
||||||
$this->fail(21, "Access denied");
|
$this->fail(21, "Access denied");
|
||||||
|
}
|
||||||
|
|
||||||
$comment->delete();
|
$comment->delete();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createComment(int $owner_id, int $photo_id, string $message = "", string $attachments = "", bool $from_group = false)
|
public function createComment(int $owner_id, int $photo_id, string $message = "", string $attachments = "", bool $from_group = false)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
if(empty($message) && empty($attachments))
|
if (empty($message) && empty($attachments)) {
|
||||||
$this->fail(100, "Required parameter 'message' missing.");
|
$this->fail(100, "Required parameter 'message' missing.");
|
||||||
|
}
|
||||||
|
|
||||||
$photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id);
|
$photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $photo_id);
|
||||||
|
|
||||||
if(!$photo || $photo->isDeleted())
|
if (!$photo || $photo->isDeleted()) {
|
||||||
$this->fail(180, "Invalid photo");
|
$this->fail(180, "Invalid photo");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$photo->canBeViewedBy($this->getUser()))
|
if (!$photo->canBeViewedBy($this->getUser())) {
|
||||||
$this->fail(15, "Access to photo denied");
|
$this->fail(15, "Access to photo denied");
|
||||||
|
}
|
||||||
|
|
||||||
$comment = new Comment;
|
$comment = new Comment();
|
||||||
$comment->setOwner($this->getUser()->getId());
|
$comment->setOwner($this->getUser()->getId());
|
||||||
$comment->setModel(get_class($photo));
|
$comment->setModel(get_class($photo));
|
||||||
$comment->setTarget($photo->getId());
|
$comment->setTarget($photo->getId());
|
||||||
|
@ -579,43 +624,49 @@ final class Photos extends VKAPIRequestHandler
|
||||||
$comment->setCreated(time());
|
$comment->setCreated(time());
|
||||||
$comment->save();
|
$comment->save();
|
||||||
|
|
||||||
if(!empty($attachments)) {
|
if (!empty($attachments)) {
|
||||||
$attachmentsArr = explode(",", $attachments);
|
$attachmentsArr = explode(",", $attachments);
|
||||||
|
|
||||||
if(sizeof($attachmentsArr) > 10)
|
if (sizeof($attachmentsArr) > 10) {
|
||||||
$this->fail(50, "Error: too many attachments");
|
$this->fail(50, "Error: too many attachments");
|
||||||
|
}
|
||||||
foreach($attachmentsArr as $attac) {
|
|
||||||
$attachmentType = NULL;
|
|
||||||
|
|
||||||
if(str_contains($attac, "photo"))
|
foreach ($attachmentsArr as $attac) {
|
||||||
|
$attachmentType = null;
|
||||||
|
|
||||||
|
if (str_contains($attac, "photo")) {
|
||||||
$attachmentType = "photo";
|
$attachmentType = "photo";
|
||||||
elseif(str_contains($attac, "video"))
|
} elseif (str_contains($attac, "video")) {
|
||||||
$attachmentType = "video";
|
$attachmentType = "video";
|
||||||
else
|
} else {
|
||||||
$this->fail(205, "Unknown attachment type");
|
$this->fail(205, "Unknown attachment type");
|
||||||
|
}
|
||||||
|
|
||||||
$attachment = str_replace($attachmentType, "", $attac);
|
$attachment = str_replace($attachmentType, "", $attac);
|
||||||
|
|
||||||
$attachmentOwner = (int)explode("_", $attachment)[0];
|
$attachmentOwner = (int) explode("_", $attachment)[0];
|
||||||
$attachmentId = (int)end(explode("_", $attachment));
|
$attachmentId = (int) end(explode("_", $attachment));
|
||||||
|
|
||||||
$attacc = NULL;
|
$attacc = null;
|
||||||
|
|
||||||
if($attachmentType == "photo") {
|
if ($attachmentType == "photo") {
|
||||||
$attacc = (new PhotosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId);
|
$attacc = (new PhotosRepo())->getByOwnerAndVID($attachmentOwner, $attachmentId);
|
||||||
if(!$attacc || $attacc->isDeleted())
|
if (!$attacc || $attacc->isDeleted()) {
|
||||||
$this->fail(100, "Photo does not exists");
|
$this->fail(100, "Photo does not exists");
|
||||||
if($attacc->getOwner()->getId() != $this->getUser()->getId())
|
}
|
||||||
|
if ($attacc->getOwner()->getId() != $this->getUser()->getId()) {
|
||||||
$this->fail(43, "You do not have access to this photo");
|
$this->fail(43, "You do not have access to this photo");
|
||||||
|
}
|
||||||
|
|
||||||
$comment->attach($attacc);
|
$comment->attach($attacc);
|
||||||
} elseif($attachmentType == "video") {
|
} elseif ($attachmentType == "video") {
|
||||||
$attacc = (new VideosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId);
|
$attacc = (new VideosRepo())->getByOwnerAndVID($attachmentOwner, $attachmentId);
|
||||||
if(!$attacc || $attacc->isDeleted())
|
if (!$attacc || $attacc->isDeleted()) {
|
||||||
$this->fail(100, "Video does not exists");
|
$this->fail(100, "Video does not exists");
|
||||||
if($attacc->getOwner()->getId() != $this->getUser()->getId())
|
}
|
||||||
|
if ($attacc->getOwner()->getId() != $this->getUser()->getId()) {
|
||||||
$this->fail(43, "You do not have access to this video");
|
$this->fail(43, "You do not have access to this video");
|
||||||
|
}
|
||||||
|
|
||||||
$comment->attach($attacc);
|
$comment->attach($attacc);
|
||||||
}
|
}
|
||||||
|
@ -625,56 +676,63 @@ final class Photos extends VKAPIRequestHandler
|
||||||
return $comment->getId();
|
return $comment->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAll(int $owner_id, bool $extended = false, int $offset = 0, int $count = 100, bool $photo_sizes = false)
|
public function getAll(int $owner_id, bool $extended = false, int $offset = 0, int $count = 100, bool $photo_sizes = false)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
if($owner_id < 0)
|
if ($owner_id < 0) {
|
||||||
$this->fail(4, "This method doesn't works with clubs");
|
$this->fail(4, "This method doesn't works with clubs");
|
||||||
|
}
|
||||||
|
|
||||||
$user = (new UsersRepo)->get($owner_id);
|
$user = (new UsersRepo())->get($owner_id);
|
||||||
if(!$user)
|
if (!$user) {
|
||||||
$this->fail(4, "Invalid user");
|
$this->fail(4, "Invalid user");
|
||||||
|
}
|
||||||
if(!$user->getPrivacyPermission('photos.read', $this->getUser()))
|
|
||||||
$this->fail(21, "This user chose to hide his albums.");
|
|
||||||
|
|
||||||
$photos = (new PhotosRepo)->getEveryUserPhoto($user, $offset, $count);
|
if (!$user->getPrivacyPermission('photos.read', $this->getUser())) {
|
||||||
|
$this->fail(21, "This user chose to hide his albums.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$photos = (new PhotosRepo())->getEveryUserPhoto($user, $offset, $count);
|
||||||
$res = [
|
$res = [
|
||||||
"count" => (new PhotosRepo)->getUserPhotosCount($user),
|
"count" => (new PhotosRepo())->getUserPhotosCount($user),
|
||||||
"items" => [],
|
"items" => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach($photos as $photo) {
|
foreach ($photos as $photo) {
|
||||||
if(!$photo || $photo->isDeleted()) continue;
|
if (!$photo || $photo->isDeleted()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$res["items"][] = $photo->toVkApiStruct($photo_sizes, $extended);
|
$res["items"][] = $photo->toVkApiStruct($photo_sizes, $extended);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComments(int $owner_id, int $photo_id, bool $need_likes = false, int $offset = 0, int $count = 100, bool $extended = false, string $fields = "")
|
public function getComments(int $owner_id, int $photo_id, bool $need_likes = false, int $offset = 0, int $count = 100, bool $extended = false, string $fields = "")
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id);
|
$photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $photo_id);
|
||||||
$comms = array_slice(iterator_to_array($photo->getComments(1, $offset + $count)), $offset);
|
$comms = array_slice(iterator_to_array($photo->getComments(1, $offset + $count)), $offset);
|
||||||
|
|
||||||
if(!$photo || $photo->isDeleted())
|
if (!$photo || $photo->isDeleted()) {
|
||||||
$this->fail(4, "Invalid photo");
|
$this->fail(4, "Invalid photo");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$photo->canBeViewedBy($this->getUser()))
|
if (!$photo->canBeViewedBy($this->getUser())) {
|
||||||
$this->fail(21, "Access denied");
|
$this->fail(21, "Access denied");
|
||||||
|
}
|
||||||
|
|
||||||
$res = [
|
$res = [
|
||||||
"count" => sizeof($comms),
|
"count" => sizeof($comms),
|
||||||
"items" => []
|
"items" => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach($comms as $comment) {
|
foreach ($comms as $comment) {
|
||||||
$res["items"][] = $comment->toVkApiStruct($this->getUser(), $need_likes, $extended);
|
$res["items"][] = $comment->toVkApiStruct($this->getUser(), $need_likes, $extended);
|
||||||
if($extended) {
|
if ($extended) {
|
||||||
if($comment->getOwner() instanceof \openvk\Web\Models\Entities\User) {
|
if ($comment->getOwner() instanceof \openvk\Web\Models\Entities\User) {
|
||||||
$res["profiles"][] = $comment->getOwner()->toVkApiStruct();
|
$res["profiles"][] = $comment->getOwner()->toVkApiStruct();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,170 +1,184 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
namespace openvk\VKAPI\Handlers;
|
|
||||||
use openvk\Web\Models\Entities\User;
|
declare(strict_types=1);
|
||||||
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
|
||||||
use openvk\Web\Models\Entities\Poll;
|
namespace openvk\VKAPI\Handlers;
|
||||||
use openvk\Web\Models\Exceptions\AlreadyVotedException;
|
|
||||||
use openvk\Web\Models\Exceptions\InvalidOptionException;
|
use openvk\Web\Models\Entities\User;
|
||||||
use openvk\Web\Models\Exceptions\PollLockedException;
|
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
||||||
use openvk\Web\Models\Repositories\Polls as PollsRepo;
|
use openvk\Web\Models\Entities\Poll;
|
||||||
|
use openvk\Web\Models\Exceptions\AlreadyVotedException;
|
||||||
final class Polls extends VKAPIRequestHandler
|
use openvk\Web\Models\Exceptions\InvalidOptionException;
|
||||||
{
|
use openvk\Web\Models\Exceptions\PollLockedException;
|
||||||
function getById(int $poll_id, bool $extended = false, string $fields = "sex,screen_name,photo_50,photo_100,online_info,online")
|
use openvk\Web\Models\Repositories\Polls as PollsRepo;
|
||||||
{
|
|
||||||
$poll = (new PollsRepo)->get($poll_id);
|
final class Polls extends VKAPIRequestHandler
|
||||||
|
{
|
||||||
if (!$poll)
|
public function getById(int $poll_id, bool $extended = false, string $fields = "sex,screen_name,photo_50,photo_100,online_info,online")
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: poll_id is incorrect");
|
{
|
||||||
|
$poll = (new PollsRepo())->get($poll_id);
|
||||||
$users = array();
|
|
||||||
$answers = array();
|
if (!$poll) {
|
||||||
foreach($poll->getResults()->options as $answer) {
|
$this->fail(100, "One of the parameters specified was missing or invalid: poll_id is incorrect");
|
||||||
$answers[] = (object)[
|
}
|
||||||
"id" => $answer->id,
|
|
||||||
"rate" => $answer->pct,
|
$users = [];
|
||||||
"text" => $answer->name,
|
$answers = [];
|
||||||
"votes" => $answer->votes
|
foreach ($poll->getResults()->options as $answer) {
|
||||||
];
|
$answers[] = (object) [
|
||||||
}
|
"id" => $answer->id,
|
||||||
|
"rate" => $answer->pct,
|
||||||
$userVote = array();
|
"text" => $answer->name,
|
||||||
foreach($poll->getUserVote($this->getUser()) as $vote)
|
"votes" => $answer->votes,
|
||||||
$userVote[] = $vote[0];
|
];
|
||||||
|
}
|
||||||
$response = [
|
|
||||||
"multiple" => $poll->isMultipleChoice(),
|
$userVote = [];
|
||||||
"end_date" => $poll->endsAt() == NULL ? 0 : $poll->endsAt()->timestamp(),
|
foreach ($poll->getUserVote($this->getUser()) as $vote) {
|
||||||
"closed" => $poll->hasEnded(),
|
$userVote[] = $vote[0];
|
||||||
"is_board" => false,
|
}
|
||||||
"can_edit" => false,
|
|
||||||
"can_vote" => $poll->canVote($this->getUser()),
|
$response = [
|
||||||
"can_report" => false,
|
"multiple" => $poll->isMultipleChoice(),
|
||||||
"can_share" => true,
|
"end_date" => $poll->endsAt() == null ? 0 : $poll->endsAt()->timestamp(),
|
||||||
"created" => 0,
|
"closed" => $poll->hasEnded(),
|
||||||
"id" => $poll->getId(),
|
"is_board" => false,
|
||||||
"owner_id" => $poll->getOwner()->getId(),
|
"can_edit" => false,
|
||||||
"question" => $poll->getTitle(),
|
"can_vote" => $poll->canVote($this->getUser()),
|
||||||
"votes" => $poll->getVoterCount(),
|
"can_report" => false,
|
||||||
"disable_unvote" => $poll->isRevotable(),
|
"can_share" => true,
|
||||||
"anonymous" => $poll->isAnonymous(),
|
"created" => 0,
|
||||||
"answer_ids" => $userVote,
|
"id" => $poll->getId(),
|
||||||
"answers" => $answers,
|
"owner_id" => $poll->getOwner()->getId(),
|
||||||
"author_id" => $poll->getOwner()->getId(),
|
"question" => $poll->getTitle(),
|
||||||
];
|
"votes" => $poll->getVoterCount(),
|
||||||
|
"disable_unvote" => $poll->isRevotable(),
|
||||||
if ($extended) {
|
"anonymous" => $poll->isAnonymous(),
|
||||||
$response["profiles"] = (new Users)->get(strval($poll->getOwner()->getId()), $fields, 0, 1);
|
"answer_ids" => $userVote,
|
||||||
/* Currently there is only one person that can be shown trough "Extended" param.
|
"answers" => $answers,
|
||||||
* As "friends" param will be implemented, "profiles" will show more users
|
"author_id" => $poll->getOwner()->getId(),
|
||||||
*/
|
];
|
||||||
}
|
|
||||||
|
if ($extended) {
|
||||||
return (object) $response;
|
$response["profiles"] = (new Users())->get(strval($poll->getOwner()->getId()), $fields, 0, 1);
|
||||||
}
|
/* Currently there is only one person that can be shown trough "Extended" param.
|
||||||
|
* As "friends" param will be implemented, "profiles" will show more users
|
||||||
function addVote(int $poll_id, string $answers_ids)
|
*/
|
||||||
{
|
}
|
||||||
$this->requireUser();
|
|
||||||
$this->willExecuteWriteAction();
|
return (object) $response;
|
||||||
|
}
|
||||||
$poll = (new PollsRepo)->get($poll_id);
|
|
||||||
|
public function addVote(int $poll_id, string $answers_ids)
|
||||||
if(!$poll)
|
{
|
||||||
$this->fail(251, "Invalid poll id");
|
$this->requireUser();
|
||||||
|
$this->willExecuteWriteAction();
|
||||||
try {
|
|
||||||
$poll->vote($this->getUser(), explode(",", $answers_ids));
|
$poll = (new PollsRepo())->get($poll_id);
|
||||||
return 1;
|
|
||||||
} catch(AlreadyVotedException $ex) {
|
if (!$poll) {
|
||||||
return 0;
|
$this->fail(251, "Invalid poll id");
|
||||||
} catch(PollLockedException $ex) {
|
}
|
||||||
return 0;
|
|
||||||
} catch(InvalidOptionException $ex) {
|
try {
|
||||||
$this->fail(8, "бдсм вибратор купить в киеве");
|
$poll->vote($this->getUser(), explode(",", $answers_ids));
|
||||||
}
|
return 1;
|
||||||
}
|
} catch (AlreadyVotedException $ex) {
|
||||||
|
return 0;
|
||||||
function deleteVote(int $poll_id)
|
} catch (PollLockedException $ex) {
|
||||||
{
|
return 0;
|
||||||
$this->requireUser();
|
} catch (InvalidOptionException $ex) {
|
||||||
$this->willExecuteWriteAction();
|
$this->fail(8, "бдсм вибратор купить в киеве");
|
||||||
|
}
|
||||||
$poll = (new PollsRepo)->get($poll_id);
|
}
|
||||||
|
|
||||||
if(!$poll)
|
public function deleteVote(int $poll_id)
|
||||||
$this->fail(251, "Invalid poll id");
|
{
|
||||||
|
$this->requireUser();
|
||||||
try {
|
$this->willExecuteWriteAction();
|
||||||
$poll->revokeVote($this->getUser());
|
|
||||||
return 1;
|
$poll = (new PollsRepo())->get($poll_id);
|
||||||
} catch(PollLockedException $ex) {
|
|
||||||
$this->fail(15, "Access denied: Poll is locked or isn't revotable");
|
if (!$poll) {
|
||||||
} catch(InvalidOptionException $ex) {
|
$this->fail(251, "Invalid poll id");
|
||||||
$this->fail(8, "how.to. ook.bacon.in.microwova.");
|
}
|
||||||
}
|
|
||||||
}
|
try {
|
||||||
|
$poll->revokeVote($this->getUser());
|
||||||
function getVoters(int $poll_id, int $answer_ids, int $offset = 0, int $count = 6)
|
return 1;
|
||||||
{
|
} catch (PollLockedException $ex) {
|
||||||
$this->requireUser();
|
$this->fail(15, "Access denied: Poll is locked or isn't revotable");
|
||||||
|
} catch (InvalidOptionException $ex) {
|
||||||
$poll = (new PollsRepo)->get($poll_id);
|
$this->fail(8, "how.to. ook.bacon.in.microwova.");
|
||||||
|
}
|
||||||
if(!$poll)
|
}
|
||||||
$this->fail(251, "Invalid poll");
|
|
||||||
|
public function getVoters(int $poll_id, int $answer_ids, int $offset = 0, int $count = 6)
|
||||||
if($poll->isAnonymous())
|
{
|
||||||
$this->fail(251, "Access denied: poll is anonymous.");
|
$this->requireUser();
|
||||||
|
|
||||||
$voters = array_slice($poll->getVoters($answer_ids, 1, $offset + $count), $offset);
|
$poll = (new PollsRepo())->get($poll_id);
|
||||||
$res = (object)[
|
|
||||||
"answer_id" => $answer_ids,
|
if (!$poll) {
|
||||||
"users" => []
|
$this->fail(251, "Invalid poll");
|
||||||
];
|
}
|
||||||
|
|
||||||
foreach($voters as $voter)
|
if ($poll->isAnonymous()) {
|
||||||
$res->users[] = $voter->toVkApiStruct();
|
$this->fail(251, "Access denied: poll is anonymous.");
|
||||||
|
}
|
||||||
return $res;
|
|
||||||
}
|
$voters = array_slice($poll->getVoters($answer_ids, 1, $offset + $count), $offset);
|
||||||
|
$res = (object) [
|
||||||
function create(string $question, string $add_answers, bool $disable_unvote = false, bool $is_anonymous = false, bool $is_multiple = false, int $end_date = 0)
|
"answer_id" => $answer_ids,
|
||||||
{
|
"users" => [],
|
||||||
$this->requireUser();
|
];
|
||||||
$this->willExecuteWriteAction();
|
|
||||||
|
foreach ($voters as $voter) {
|
||||||
$options = json_decode($add_answers);
|
$res->users[] = $voter->toVkApiStruct();
|
||||||
|
}
|
||||||
if(!$options || empty($options))
|
|
||||||
$this->fail(62, "Invalid options");
|
return $res;
|
||||||
|
}
|
||||||
if(sizeof($options) > ovkGetQuirk("polls.max-opts"))
|
|
||||||
$this->fail(51, "Too many options");
|
public function create(string $question, string $add_answers, bool $disable_unvote = false, bool $is_anonymous = false, bool $is_multiple = false, int $end_date = 0)
|
||||||
|
{
|
||||||
$poll = new Poll;
|
$this->requireUser();
|
||||||
$poll->setOwner($this->getUser());
|
$this->willExecuteWriteAction();
|
||||||
$poll->setTitle($question);
|
|
||||||
$poll->setMultipleChoice($is_multiple);
|
$options = json_decode($add_answers);
|
||||||
$poll->setAnonymity($is_anonymous);
|
|
||||||
$poll->setRevotability(!$disable_unvote);
|
if (!$options || empty($options)) {
|
||||||
$poll->setOptions($options);
|
$this->fail(62, "Invalid options");
|
||||||
|
}
|
||||||
if($end_date > time()) {
|
|
||||||
if($end_date > time() + (DAY * 365))
|
if (sizeof($options) > ovkGetQuirk("polls.max-opts")) {
|
||||||
$this->fail(89, "End date is too big");
|
$this->fail(51, "Too many options");
|
||||||
|
}
|
||||||
$poll->setEndDate($end_date);
|
|
||||||
}
|
$poll = new Poll();
|
||||||
|
$poll->setOwner($this->getUser());
|
||||||
$poll->save();
|
$poll->setTitle($question);
|
||||||
|
$poll->setMultipleChoice($is_multiple);
|
||||||
return $this->getById($poll->getId());
|
$poll->setAnonymity($is_anonymous);
|
||||||
}
|
$poll->setRevotability(!$disable_unvote);
|
||||||
|
$poll->setOptions($options);
|
||||||
function edit()
|
|
||||||
{
|
if ($end_date > time()) {
|
||||||
#todo
|
if ($end_date > time() + (DAY * 365)) {
|
||||||
return 1;
|
$this->fail(89, "End date is too big");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
$poll->setEndDate($end_date);
|
||||||
|
}
|
||||||
|
|
||||||
|
$poll->save();
|
||||||
|
|
||||||
|
return $this->getById($poll->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit()
|
||||||
|
{
|
||||||
|
#todo
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,42 +1,46 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\Report;
|
use openvk\Web\Models\Entities\Report;
|
||||||
use openvk\Web\Models\Repositories\Reports as ReportsRepo;
|
use openvk\Web\Models\Repositories\Reports as ReportsRepo;
|
||||||
|
|
||||||
final class Reports extends VKAPIRequestHandler
|
final class Reports extends VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
function add(int $owner_id = 0, string $comment = "", int $reason = 0, string $type = "", string $report_source = ""): int
|
public function add(int $owner_id = 0, string $comment = "", int $reason = 0, string $type = "", string $report_source = ""): int
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
$allowed_types = ["post", "photo", "video", "group", "comment", "note", "app", "user", "audio"];
|
$allowed_types = ["post", "photo", "video", "group", "comment", "note", "app", "user", "audio"];
|
||||||
if($type == "" || !in_array($type, $allowed_types)) {
|
if ($type == "" || !in_array($type, $allowed_types)) {
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: type should be ".implode(", ", $allowed_types));
|
$this->fail(100, "One of the parameters specified was missing or invalid: type should be " . implode(", ", $allowed_types));
|
||||||
}
|
}
|
||||||
|
|
||||||
if($owner_id <= 0) {
|
if ($owner_id <= 0) {
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: Bad input");
|
$this->fail(100, "One of the parameters specified was missing or invalid: Bad input");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mb_strlen($comment) === 0) {
|
if (mb_strlen($comment) === 0) {
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: Comment can't be empty");
|
$this->fail(100, "One of the parameters specified was missing or invalid: Comment can't be empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
if($type == "user" && $owner_id == $this->getUser()->getId()) {
|
if ($type == "user" && $owner_id == $this->getUser()->getId()) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->getUser()->isBannedInSupport()) {
|
if ($this->getUser()->isBannedInSupport()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sizeof(iterator_to_array((new ReportsRepo)->getDuplicates($type, $owner_id, NULL, $this->getUser()->getId()))) > 0) {
|
if (sizeof(iterator_to_array((new ReportsRepo())->getDuplicates($type, $owner_id, null, $this->getUser()->getId()))) > 0) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$report = new Report;
|
$report = new Report();
|
||||||
$report->setUser_id($this->getUser()->getId());
|
$report->setUser_id($this->getUser()->getId());
|
||||||
$report->setTarget_id($owner_id);
|
$report->setTarget_id($owner_id);
|
||||||
$report->setType($type);
|
$report->setType($type);
|
||||||
|
@ -44,7 +48,7 @@ final class Reports extends VKAPIRequestHandler
|
||||||
$report->setCreated(time());
|
$report->setCreated(time());
|
||||||
|
|
||||||
$report->save();
|
$report->save();
|
||||||
} catch(\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$this->fail(-1, "Unknown error failed");
|
$this->fail(-1, "Unknown error failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,33 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
||||||
|
|
||||||
final class Status extends VKAPIRequestHandler
|
final class Status extends VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
function get(int $user_id = 0, int $group_id = 0)
|
public function get(int $user_id = 0, int $group_id = 0)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
if($user_id == 0 && $group_id == 0)
|
if ($user_id == 0 && $group_id == 0) {
|
||||||
$user_id = $this->getUser()->getId();
|
$user_id = $this->getUser()->getId();
|
||||||
|
}
|
||||||
|
|
||||||
if($group_id > 0)
|
if ($group_id > 0) {
|
||||||
$this->fail(501, "Group statuses are not implemented");
|
$this->fail(501, "Group statuses are not implemented");
|
||||||
else {
|
} else {
|
||||||
$user = (new UsersRepo)->get($user_id);
|
$user = (new UsersRepo())->get($user_id);
|
||||||
|
|
||||||
if(!$user || $user->isDeleted() || !$user->canBeViewedBy($this->getUser()))
|
if (!$user || $user->isDeleted() || !$user->canBeViewedBy($this->getUser())) {
|
||||||
$this->fail(15, "Invalid user");
|
$this->fail(15, "Invalid user");
|
||||||
|
}
|
||||||
|
|
||||||
$audioStatus = $user->getCurrentAudioStatus();
|
$audioStatus = $user->getCurrentAudioStatus();
|
||||||
if($audioStatus) {
|
if ($audioStatus) {
|
||||||
return [
|
return [
|
||||||
"status" => $user->getStatus(),
|
"status" => $user->getStatus(),
|
||||||
"audio" => $audioStatus->toVkApiStruct(),
|
"audio" => $audioStatus->toVkApiStruct(),
|
||||||
|
@ -32,17 +38,17 @@ final class Status extends VKAPIRequestHandler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function set(string $text, int $group_id = 0)
|
public function set(string $text, int $group_id = 0)
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
if($group_id > 0) {
|
if ($group_id > 0) {
|
||||||
$this->fail(501, "Group statuses are not implemented");
|
$this->fail(501, "Group statuses are not implemented");
|
||||||
} else {
|
} else {
|
||||||
$this->getUser()->setStatus($text);
|
$this->getUser()->setStatus($text);
|
||||||
$this->getUser()->save();
|
$this->getUser()->save();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\{User, Report};
|
use openvk\Web\Models\Entities\{User, Report};
|
||||||
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
||||||
use openvk\Web\Models\Repositories\{Photos, Clubs, Albums, Videos, Notes, Audios};
|
use openvk\Web\Models\Repositories\{Photos, Clubs, Albums, Videos, Notes, Audios};
|
||||||
|
@ -7,378 +11,392 @@ use openvk\Web\Models\Repositories\Reports;
|
||||||
|
|
||||||
final class Users extends VKAPIRequestHandler
|
final class Users extends VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
function get(string $user_ids = "0", string $fields = "", int $offset = 0, int $count = 100, User $authuser = null /* костыль(( */): array
|
public function get(string $user_ids = "0", string $fields = "", int $offset = 0, int $count = 100, User $authuser = null /* костыль(( */): array
|
||||||
{
|
{
|
||||||
if($authuser == NULL) $authuser = $this->getUser();
|
if ($authuser == null) {
|
||||||
|
$authuser = $this->getUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
$users = new UsersRepo();
|
||||||
|
if ($user_ids == "0") {
|
||||||
|
if (!$authuser) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$user_ids = (string) $authuser->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$users = new UsersRepo;
|
|
||||||
if($user_ids == "0") {
|
|
||||||
if(!$authuser) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$user_ids = (string) $authuser->getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$usrs = explode(',', $user_ids);
|
$usrs = explode(',', $user_ids);
|
||||||
$response = array();
|
$response = [];
|
||||||
|
|
||||||
$ic = sizeof($usrs);
|
$ic = sizeof($usrs);
|
||||||
|
|
||||||
if(sizeof($usrs) > $count)
|
if (sizeof($usrs) > $count) {
|
||||||
$ic = $count;
|
$ic = $count;
|
||||||
|
}
|
||||||
|
|
||||||
$usrs = array_slice($usrs, $offset * $count);
|
$usrs = array_slice($usrs, $offset * $count);
|
||||||
|
|
||||||
for($i=0; $i < $ic; $i++) {
|
for ($i = 0; $i < $ic; $i++) {
|
||||||
if($usrs[$i] != 0) {
|
if ($usrs[$i] != 0) {
|
||||||
$usr = $users->get((int) $usrs[$i]);
|
$usr = $users->get((int) $usrs[$i]);
|
||||||
if(is_null($usr) || $usr->isDeleted()) {
|
if (is_null($usr) || $usr->isDeleted()) {
|
||||||
$response[$i] = (object)[
|
$response[$i] = (object) [
|
||||||
"id" => (int) $usrs[$i],
|
"id" => (int) $usrs[$i],
|
||||||
"first_name" => "DELETED",
|
"first_name" => "DELETED",
|
||||||
"last_name" => "",
|
"last_name" => "",
|
||||||
"deactivated" => "deleted"
|
"deactivated" => "deleted",
|
||||||
];
|
];
|
||||||
} else if($usr->isBanned()) {
|
} elseif ($usr->isBanned()) {
|
||||||
$response[$i] = (object)[
|
$response[$i] = (object) [
|
||||||
"id" => $usr->getId(),
|
"id" => $usr->getId(),
|
||||||
"first_name" => $usr->getFirstName(true),
|
"first_name" => $usr->getFirstName(true),
|
||||||
"last_name" => $usr->getLastName(true),
|
"last_name" => $usr->getLastName(true),
|
||||||
"deactivated" => "banned",
|
"deactivated" => "banned",
|
||||||
"ban_reason" => $usr->getBanReason()
|
"ban_reason" => $usr->getBanReason(),
|
||||||
];
|
];
|
||||||
} else if($usrs[$i] == NULL) {
|
} elseif ($usrs[$i] == null) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$response[$i] = (object)[
|
$response[$i] = (object) [
|
||||||
"id" => $usr->getId(),
|
"id" => $usr->getId(),
|
||||||
"first_name" => $usr->getFirstName(true),
|
"first_name" => $usr->getFirstName(true),
|
||||||
"last_name" => $usr->getLastName(true),
|
"last_name" => $usr->getLastName(true),
|
||||||
"is_closed" => $usr->isClosed(),
|
"is_closed" => $usr->isClosed(),
|
||||||
"can_access_closed" => (bool)$usr->canBeViewedBy($this->getUser()),
|
"can_access_closed" => (bool) $usr->canBeViewedBy($this->getUser()),
|
||||||
];
|
];
|
||||||
|
|
||||||
$flds = explode(',', $fields);
|
$flds = explode(',', $fields);
|
||||||
$canView = $usr->canBeViewedBy($this->getUser());
|
$canView = $usr->canBeViewedBy($this->getUser());
|
||||||
foreach($flds as $field) {
|
foreach ($flds as $field) {
|
||||||
switch($field) {
|
switch ($field) {
|
||||||
case "verified":
|
case "verified":
|
||||||
$response[$i]->verified = intval($usr->isVerified());
|
$response[$i]->verified = intval($usr->isVerified());
|
||||||
break;
|
break;
|
||||||
case "sex":
|
case "sex":
|
||||||
$response[$i]->sex = $usr->isFemale() ? 1 : ($usr->isNeutral() ? 0 : 2);
|
$response[$i]->sex = $usr->isFemale() ? 1 : ($usr->isNeutral() ? 0 : 2);
|
||||||
break;
|
break;
|
||||||
case "has_photo":
|
case "has_photo":
|
||||||
$response[$i]->has_photo = is_null($usr->getAvatarPhoto()) ? 0 : 1;
|
$response[$i]->has_photo = is_null($usr->getAvatarPhoto()) ? 0 : 1;
|
||||||
break;
|
break;
|
||||||
case "photo_max_orig":
|
case "photo_max_orig":
|
||||||
$response[$i]->photo_max_orig = $usr->getAvatarURL();
|
$response[$i]->photo_max_orig = $usr->getAvatarURL();
|
||||||
break;
|
break;
|
||||||
case "photo_max":
|
case "photo_max":
|
||||||
$response[$i]->photo_max = $usr->getAvatarURL("original");
|
$response[$i]->photo_max = $usr->getAvatarURL("original");
|
||||||
break;
|
break;
|
||||||
case "photo_50":
|
case "photo_50":
|
||||||
$response[$i]->photo_50 = $usr->getAvatarURL();
|
$response[$i]->photo_50 = $usr->getAvatarURL();
|
||||||
break;
|
break;
|
||||||
case "photo_100":
|
case "photo_100":
|
||||||
$response[$i]->photo_100 = $usr->getAvatarURL("tiny");
|
$response[$i]->photo_100 = $usr->getAvatarURL("tiny");
|
||||||
break;
|
break;
|
||||||
case "photo_200":
|
case "photo_200":
|
||||||
$response[$i]->photo_200 = $usr->getAvatarURL("normal");
|
$response[$i]->photo_200 = $usr->getAvatarURL("normal");
|
||||||
break;
|
break;
|
||||||
case "photo_200_orig": # вообще не ебу к чему эта строка ну пусть будет кек
|
case "photo_200_orig": # вообще не ебу к чему эта строка ну пусть будет кек
|
||||||
$response[$i]->photo_200_orig = $usr->getAvatarURL("normal");
|
$response[$i]->photo_200_orig = $usr->getAvatarURL("normal");
|
||||||
break;
|
break;
|
||||||
case "photo_400_orig":
|
case "photo_400_orig":
|
||||||
$response[$i]->photo_400_orig = $usr->getAvatarURL("normal");
|
$response[$i]->photo_400_orig = $usr->getAvatarURL("normal");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
# Она хочет быть выебанной видя матан
|
|
||||||
# Покайфу когда ты Виет а вокруг лишь дискриминант
|
|
||||||
|
|
||||||
# ору а когда я это успел написать
|
# Она хочет быть выебанной видя матан
|
||||||
# вова кстати не матерись в коде мамка же спалит азщазаззазщазазаззазазазх
|
# Покайфу когда ты Виет а вокруг лишь дискриминант
|
||||||
case "status":
|
|
||||||
if($usr->getStatus() != NULL)
|
|
||||||
$response[$i]->status = $usr->getStatus();
|
|
||||||
|
|
||||||
$audioStatus = $usr->getCurrentAudioStatus();
|
|
||||||
|
|
||||||
if($audioStatus)
|
# ору а когда я это успел написать
|
||||||
$response[$i]->status_audio = $audioStatus->toVkApiStruct();
|
# вова кстати не матерись в коде мамка же спалит азщазаззазщазазаззазазазх
|
||||||
|
case "status":
|
||||||
|
if ($usr->getStatus() != null) {
|
||||||
|
$response[$i]->status = $usr->getStatus();
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
$audioStatus = $usr->getCurrentAudioStatus();
|
||||||
case "screen_name":
|
|
||||||
if($usr->getShortCode() != NULL)
|
|
||||||
$response[$i]->screen_name = $usr->getShortCode();
|
|
||||||
break;
|
|
||||||
case "friend_status":
|
|
||||||
switch($usr->getSubscriptionStatus($authuser)) {
|
|
||||||
case 3:
|
|
||||||
# NOTICE falling through
|
|
||||||
case 0:
|
|
||||||
$response[$i]->friend_status = $usr->getSubscriptionStatus($authuser);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
$response[$i]->friend_status = 2;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
$response[$i]->friend_status = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "last_seen":
|
|
||||||
if ($usr->onlineStatus() == 0) {
|
|
||||||
$platform = $usr->getOnlinePlatform(true);
|
|
||||||
switch ($platform) {
|
|
||||||
case 'iphone':
|
|
||||||
$platform = 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'android':
|
if ($audioStatus) {
|
||||||
$platform = 4;
|
$response[$i]->status_audio = $audioStatus->toVkApiStruct();
|
||||||
break;
|
}
|
||||||
|
|
||||||
case NULL:
|
break;
|
||||||
$platform = 7;
|
case "screen_name":
|
||||||
break;
|
if ($usr->getShortCode() != null) {
|
||||||
|
$response[$i]->screen_name = $usr->getShortCode();
|
||||||
default:
|
}
|
||||||
$platform = 1;
|
break;
|
||||||
break;
|
case "friend_status":
|
||||||
}
|
switch ($usr->getSubscriptionStatus($authuser)) {
|
||||||
|
case 3:
|
||||||
|
# NOTICE falling through
|
||||||
|
case 0:
|
||||||
|
$response[$i]->friend_status = $usr->getSubscriptionStatus($authuser);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
$response[$i]->friend_status = 2;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$response[$i]->friend_status = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "last_seen":
|
||||||
|
if ($usr->onlineStatus() == 0) {
|
||||||
|
$platform = $usr->getOnlinePlatform(true);
|
||||||
|
switch ($platform) {
|
||||||
|
case 'iphone':
|
||||||
|
$platform = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
$response[$i]->last_seen = (object) [
|
case 'android':
|
||||||
"platform" => $platform,
|
$platform = 4;
|
||||||
"time" => $usr->getOnline()->timestamp()
|
break;
|
||||||
];
|
|
||||||
}
|
|
||||||
case "music":
|
|
||||||
if(!$canView) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$response[$i]->music = $usr->getFavoriteMusic();
|
case null:
|
||||||
break;
|
$platform = 7;
|
||||||
case "movies":
|
break;
|
||||||
if(!$canView) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$response[$i]->movies = $usr->getFavoriteFilms();
|
default:
|
||||||
break;
|
$platform = 1;
|
||||||
case "tv":
|
break;
|
||||||
if(!$canView) {
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$response[$i]->tv = $usr->getFavoriteShows();
|
$response[$i]->last_seen = (object) [
|
||||||
break;
|
"platform" => $platform,
|
||||||
case "books":
|
"time" => $usr->getOnline()->timestamp(),
|
||||||
if(!$canView) {
|
];
|
||||||
break;
|
}
|
||||||
}
|
// no break
|
||||||
|
case "music":
|
||||||
|
if (!$canView) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
$response[$i]->books = $usr->getFavoriteBooks();
|
$response[$i]->music = $usr->getFavoriteMusic();
|
||||||
break;
|
break;
|
||||||
case "city":
|
case "movies":
|
||||||
if(!$canView) {
|
if (!$canView) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$response[$i]->city = $usr->getCity();
|
$response[$i]->movies = $usr->getFavoriteFilms();
|
||||||
break;
|
break;
|
||||||
case "interests":
|
case "tv":
|
||||||
if(!$canView) {
|
if (!$canView) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$response[$i]->interests = $usr->getInterests();
|
$response[$i]->tv = $usr->getFavoriteShows();
|
||||||
break;
|
break;
|
||||||
case "quotes":
|
case "books":
|
||||||
if(!$canView) {
|
if (!$canView) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$response[$i]->quotes = $usr->getFavoriteQuote();
|
$response[$i]->books = $usr->getFavoriteBooks();
|
||||||
break;
|
break;
|
||||||
case "games":
|
case "city":
|
||||||
if(!$canView) {
|
if (!$canView) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$response[$i]->games = $usr->getFavoriteGames();
|
$response[$i]->city = $usr->getCity();
|
||||||
break;
|
break;
|
||||||
case "email":
|
case "interests":
|
||||||
if(!$canView) {
|
if (!$canView) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$response[$i]->email = $usr->getContactEmail();
|
$response[$i]->interests = $usr->getInterests();
|
||||||
break;
|
break;
|
||||||
case "telegram":
|
case "quotes":
|
||||||
if(!$canView) {
|
if (!$canView) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$response[$i]->telegram = $usr->getTelegram();
|
$response[$i]->quotes = $usr->getFavoriteQuote();
|
||||||
break;
|
break;
|
||||||
case "about":
|
case "games":
|
||||||
if(!$canView) {
|
if (!$canView) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$response[$i]->about = $usr->getDescription();
|
|
||||||
break;
|
|
||||||
case "rating":
|
|
||||||
if(!$canView) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$response[$i]->rating = $usr->getRating();
|
$response[$i]->games = $usr->getFavoriteGames();
|
||||||
break;
|
break;
|
||||||
case "counters":
|
case "email":
|
||||||
$response[$i]->counters = (object) [
|
if (!$canView) {
|
||||||
"friends_count" => $usr->getFriendsCount(),
|
break;
|
||||||
"photos_count" => (new Photos)->getUserPhotosCount($usr),
|
}
|
||||||
"videos_count" => (new Videos)->getUserVideosCount($usr),
|
|
||||||
"audios_count" => (new Audios)->getUserCollectionSize($usr),
|
$response[$i]->email = $usr->getContactEmail();
|
||||||
"notes_count" => (new Notes)->getUserNotesCount($usr)
|
break;
|
||||||
];
|
case "telegram":
|
||||||
break;
|
if (!$canView) {
|
||||||
case "correct_counters":
|
break;
|
||||||
$response[$i]->counters = (object) [
|
}
|
||||||
"friends" => $usr->getFriendsCount(),
|
|
||||||
"photos" => (new Photos)->getUserPhotosCount($usr),
|
$response[$i]->telegram = $usr->getTelegram();
|
||||||
"videos" => (new Videos)->getUserVideosCount($usr),
|
break;
|
||||||
"audios" => (new Audios)->getUserCollectionSize($usr),
|
case "about":
|
||||||
"notes" => (new Notes)->getUserNotesCount($usr),
|
if (!$canView) {
|
||||||
"groups" => $usr->getClubCount(),
|
break;
|
||||||
"online_friends" => $usr->getFriendsOnlineCount(),
|
}
|
||||||
];
|
|
||||||
break;
|
$response[$i]->about = $usr->getDescription();
|
||||||
|
break;
|
||||||
|
case "rating":
|
||||||
|
if (!$canView) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$response[$i]->rating = $usr->getRating();
|
||||||
|
break;
|
||||||
|
case "counters":
|
||||||
|
$response[$i]->counters = (object) [
|
||||||
|
"friends_count" => $usr->getFriendsCount(),
|
||||||
|
"photos_count" => (new Photos())->getUserPhotosCount($usr),
|
||||||
|
"videos_count" => (new Videos())->getUserVideosCount($usr),
|
||||||
|
"audios_count" => (new Audios())->getUserCollectionSize($usr),
|
||||||
|
"notes_count" => (new Notes())->getUserNotesCount($usr),
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
case "correct_counters":
|
||||||
|
$response[$i]->counters = (object) [
|
||||||
|
"friends" => $usr->getFriendsCount(),
|
||||||
|
"photos" => (new Photos())->getUserPhotosCount($usr),
|
||||||
|
"videos" => (new Videos())->getUserVideosCount($usr),
|
||||||
|
"audios" => (new Audios())->getUserCollectionSize($usr),
|
||||||
|
"notes" => (new Notes())->getUserNotesCount($usr),
|
||||||
|
"groups" => $usr->getClubCount(),
|
||||||
|
"online_friends" => $usr->getFriendsOnlineCount(),
|
||||||
|
];
|
||||||
|
break;
|
||||||
case "guid":
|
case "guid":
|
||||||
$response[$i]->guid = $usr->getChandlerGUID();
|
$response[$i]->guid = $usr->getChandlerGUID();
|
||||||
break;
|
break;
|
||||||
case 'background':
|
case 'background':
|
||||||
$backgrounds = $usr->getBackDropPictureURLs();
|
$backgrounds = $usr->getBackDropPictureURLs();
|
||||||
$response[$i]->background = $backgrounds;
|
$response[$i]->background = $backgrounds;
|
||||||
break;
|
break;
|
||||||
case 'reg_date':
|
case 'reg_date':
|
||||||
if(!$canView) {
|
if (!$canView) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$response[$i]->reg_date = $usr->getRegistrationTime()->timestamp();
|
|
||||||
break;
|
|
||||||
case 'is_dead':
|
|
||||||
$response[$i]->is_dead = $usr->isDead();
|
|
||||||
break;
|
|
||||||
case 'nickname':
|
|
||||||
$response[$i]->nickname = $usr->getPseudo();
|
|
||||||
break;
|
|
||||||
case 'blacklisted_by_me':
|
|
||||||
if(!$authuser) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$response[$i]->blacklisted_by_me = (int)$usr->isBlacklistedBy($this->getUser());
|
$response[$i]->reg_date = $usr->getRegistrationTime()->timestamp();
|
||||||
break;
|
break;
|
||||||
case 'blacklisted':
|
case 'is_dead':
|
||||||
if(!$authuser) {
|
$response[$i]->is_dead = $usr->isDead();
|
||||||
continue;
|
break;
|
||||||
}
|
case 'nickname':
|
||||||
|
$response[$i]->nickname = $usr->getPseudo();
|
||||||
$response[$i]->blacklisted = (int)$this->getUser()->isBlacklistedBy($usr);
|
break;
|
||||||
break;
|
case 'blacklisted_by_me':
|
||||||
case "custom_fields":
|
if (!$authuser) {
|
||||||
if(sizeof($usrs) > 1)
|
continue;
|
||||||
break;
|
}
|
||||||
|
|
||||||
$c_fields = \openvk\Web\Models\Entities\UserInfoEntities\AdditionalField::getByOwner($usr->getId());
|
$response[$i]->blacklisted_by_me = (int) $usr->isBlacklistedBy($this->getUser());
|
||||||
$append_array = [];
|
break;
|
||||||
foreach($c_fields as $c_field)
|
case 'blacklisted':
|
||||||
$append_array[] = $c_field->toVkApiStruct();
|
if (!$authuser) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$response[$i]->custom_fields = $append_array;
|
$response[$i]->blacklisted = (int) $this->getUser()->isBlacklistedBy($usr);
|
||||||
break;
|
break;
|
||||||
}
|
case "custom_fields":
|
||||||
}
|
if (sizeof($usrs) > 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if($usr->getOnline()->timestamp() + 300 > time())
|
$c_fields = \openvk\Web\Models\Entities\UserInfoEntities\AdditionalField::getByOwner($usr->getId());
|
||||||
$response[$i]->online = 1;
|
$append_array = [];
|
||||||
else
|
foreach ($c_fields as $c_field) {
|
||||||
$response[$i]->online = 0;
|
$append_array[] = $c_field->toVkApiStruct();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
$response[$i]->custom_fields = $append_array;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($usr->getOnline()->timestamp() + 300 > time()) {
|
||||||
|
$response[$i]->online = 1;
|
||||||
|
} else {
|
||||||
|
$response[$i]->online = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFollowers(int $user_id, string $fields = "", int $offset = 0, int $count = 100): object
|
public function getFollowers(int $user_id, string $fields = "", int $offset = 0, int $count = 100): object
|
||||||
{
|
{
|
||||||
$offset++;
|
$offset++;
|
||||||
$followers = [];
|
$followers = [];
|
||||||
|
|
||||||
$users = new UsersRepo;
|
$users = new UsersRepo();
|
||||||
|
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$user = $users->get($user_id);
|
$user = $users->get($user_id);
|
||||||
|
|
||||||
if(!$user || $user->isDeleted())
|
if (!$user || $user->isDeleted()) {
|
||||||
$this->fail(14, "Invalid user");
|
$this->fail(14, "Invalid user");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$user->canBeViewedBy($this->getUser()))
|
if (!$user->canBeViewedBy($this->getUser())) {
|
||||||
$this->fail(15, "Access denied");
|
$this->fail(15, "Access denied");
|
||||||
|
}
|
||||||
|
|
||||||
foreach($users->get($user_id)->getFollowers($offset, $count) as $follower)
|
foreach ($users->get($user_id)->getFollowers($offset, $count) as $follower) {
|
||||||
$followers[] = $follower->getId();
|
$followers[] = $follower->getId();
|
||||||
|
}
|
||||||
|
|
||||||
$response = $followers;
|
$response = $followers;
|
||||||
|
|
||||||
if(!is_null($fields))
|
if (!is_null($fields)) {
|
||||||
$response = $this->get(implode(',', $followers), $fields, 0, $count);
|
$response = $this->get(implode(',', $followers), $fields, 0, $count);
|
||||||
|
}
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
"count" => $users->get($user_id)->getFollowersCount(),
|
"count" => $users->get($user_id)->getFollowersCount(),
|
||||||
"items" => $response
|
"items" => $response,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function search(string $q,
|
public function search(
|
||||||
string $fields = "",
|
string $q,
|
||||||
int $offset = 0,
|
string $fields = "",
|
||||||
int $count = 100,
|
int $offset = 0,
|
||||||
string $city = "",
|
int $count = 100,
|
||||||
string $hometown = "",
|
string $city = "",
|
||||||
int $sex = 3,
|
string $hometown = "",
|
||||||
int $status = 0, # marital_status
|
int $sex = 3,
|
||||||
bool $online = false,
|
int $status = 0, # marital_status
|
||||||
# non standart params:
|
bool $online = false,
|
||||||
int $sort = 0,
|
# non standart params:
|
||||||
int $polit_views = 0,
|
int $sort = 0,
|
||||||
string $fav_music = "",
|
int $polit_views = 0,
|
||||||
string $fav_films = "",
|
string $fav_music = "",
|
||||||
string $fav_shows = "",
|
string $fav_films = "",
|
||||||
string $fav_books = ""
|
string $fav_shows = "",
|
||||||
)
|
string $fav_books = ""
|
||||||
{
|
) {
|
||||||
if($count > 100) {
|
if ($count > 100) {
|
||||||
$this->fail(100, "One of the parameters specified was missing or invalid: count should be less or equal to 100");
|
$this->fail(100, "One of the parameters specified was missing or invalid: count should be less or equal to 100");
|
||||||
}
|
}
|
||||||
|
|
||||||
$users = new UsersRepo;
|
$users = new UsersRepo();
|
||||||
$output_sort = ['type' => 'id', 'invert' => false];
|
$output_sort = ['type' => 'id', 'invert' => false];
|
||||||
$output_params = [
|
$output_params = [
|
||||||
"ignore_private" => true,
|
"ignore_private" => true,
|
||||||
];
|
];
|
||||||
|
|
||||||
switch($sort) {
|
switch ($sort) {
|
||||||
default:
|
default:
|
||||||
case 0:
|
case 0:
|
||||||
$output_sort = ['type' => 'id', 'invert' => false];
|
$output_sort = ['type' => 'id', 'invert' => false];
|
||||||
break;
|
break;
|
||||||
|
@ -386,50 +404,62 @@ final class Users extends VKAPIRequestHandler
|
||||||
$output_sort = ['type' => 'id', 'invert' => true];
|
$output_sort = ['type' => 'id', 'invert' => true];
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
$output_sort = ['type' => 'rating', 'invert' => false];
|
$output_sort = ['type' => 'rating', 'invert' => false];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!empty($city))
|
if (!empty($city)) {
|
||||||
$output_params['city'] = $city;
|
$output_params['city'] = $city;
|
||||||
|
}
|
||||||
|
|
||||||
if(!empty($hometown))
|
if (!empty($hometown)) {
|
||||||
$output_params['hometown'] = $hometown;
|
$output_params['hometown'] = $hometown;
|
||||||
|
}
|
||||||
|
|
||||||
if($sex != 3)
|
if ($sex != 3) {
|
||||||
$output_params['gender'] = $sex;
|
$output_params['gender'] = $sex;
|
||||||
|
}
|
||||||
|
|
||||||
if($status != 0)
|
if ($status != 0) {
|
||||||
$output_params['marital_status'] = $status;
|
$output_params['marital_status'] = $status;
|
||||||
|
}
|
||||||
if($polit_views != 0)
|
|
||||||
$output_params['polit_views'] = $polit_views;
|
|
||||||
|
|
||||||
if(!empty($interests))
|
if ($polit_views != 0) {
|
||||||
|
$output_params['polit_views'] = $polit_views;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($interests)) {
|
||||||
$output_params['interests'] = $interests;
|
$output_params['interests'] = $interests;
|
||||||
|
}
|
||||||
|
|
||||||
if(!empty($fav_music))
|
if (!empty($fav_music)) {
|
||||||
$output_params['fav_music'] = $fav_music;
|
$output_params['fav_music'] = $fav_music;
|
||||||
|
}
|
||||||
|
|
||||||
if(!empty($fav_films))
|
if (!empty($fav_films)) {
|
||||||
$output_params['fav_films'] = $fav_films;
|
$output_params['fav_films'] = $fav_films;
|
||||||
|
}
|
||||||
|
|
||||||
if(!empty($fav_shows))
|
if (!empty($fav_shows)) {
|
||||||
$output_params['fav_shows'] = $fav_shows;
|
$output_params['fav_shows'] = $fav_shows;
|
||||||
|
}
|
||||||
if(!empty($fav_books))
|
|
||||||
$output_params['fav_books'] = $fav_books;
|
|
||||||
|
|
||||||
if($online)
|
if (!empty($fav_books)) {
|
||||||
|
$output_params['fav_books'] = $fav_books;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($online) {
|
||||||
$output_params['is_online'] = 1;
|
$output_params['is_online'] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
$array = [];
|
$array = [];
|
||||||
$find = $users->find($q, $output_params, $output_sort);
|
$find = $users->find($q, $output_params, $output_sort);
|
||||||
|
|
||||||
foreach ($find->offsetLimit($offset, $count) as $user)
|
foreach ($find->offsetLimit($offset, $count) as $user) {
|
||||||
$array[] = $user->getId();
|
$array[] = $user->getId();
|
||||||
|
}
|
||||||
|
|
||||||
if(!$array || sizeof($array) < 1) {
|
if (!$array || sizeof($array) < 1) {
|
||||||
return (object) [
|
return (object) [
|
||||||
"count" => 0,
|
"count" => 0,
|
||||||
"items" => [],
|
"items" => [],
|
||||||
|
@ -438,29 +468,31 @@ final class Users extends VKAPIRequestHandler
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
"count" => $find->size(),
|
"count" => $find->size(),
|
||||||
"items" => $this->get(implode(',', $array), $fields)
|
"items" => $this->get(implode(',', $array), $fields),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function report(int $user_id, string $type = "spam", string $comment = "")
|
public function report(int $user_id, string $type = "spam", string $comment = "")
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
$this->willExecuteWriteAction();
|
$this->willExecuteWriteAction();
|
||||||
|
|
||||||
if($user_id == $this->getUser()->getId())
|
if ($user_id == $this->getUser()->getId()) {
|
||||||
$this->fail(12, "Can't report yourself.");
|
$this->fail(12, "Can't report yourself.");
|
||||||
|
}
|
||||||
|
|
||||||
if(sizeof(iterator_to_array((new Reports)->getDuplicates("user", $user_id, NULL, $this->getUser()->getId()))) > 0)
|
if (sizeof(iterator_to_array((new Reports())->getDuplicates("user", $user_id, null, $this->getUser()->getId()))) > 0) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
$report = new Report;
|
$report = new Report();
|
||||||
$report->setUser_id($this->getUser()->getId());
|
$report->setUser_id($this->getUser()->getId());
|
||||||
$report->setTarget_id($user_id);
|
$report->setTarget_id($user_id);
|
||||||
$report->setType("user");
|
$report->setType("user");
|
||||||
$report->setReason($comment);
|
$report->setReason($comment);
|
||||||
$report->setCreated(time());
|
$report->setCreated(time());
|
||||||
$report->save();
|
$report->save();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +1,62 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
namespace openvk\VKAPI\Handlers;
|
|
||||||
use openvk\Web\Models\Repositories\{Users, Clubs};
|
declare(strict_types=1);
|
||||||
|
|
||||||
final class Utils extends VKAPIRequestHandler
|
namespace openvk\VKAPI\Handlers;
|
||||||
{
|
|
||||||
function getServerTime(): int
|
use openvk\Web\Models\Repositories\{Users, Clubs};
|
||||||
{
|
|
||||||
return time();
|
final class Utils extends VKAPIRequestHandler
|
||||||
}
|
{
|
||||||
|
public function getServerTime(): int
|
||||||
function resolveScreenName(string $screen_name): object
|
{
|
||||||
{
|
return time();
|
||||||
if(\Chandler\MVC\Routing\Router::i()->getMatchingRoute("/$screen_name")[0]->presenter !== "UnknownTextRouteStrategy") {
|
}
|
||||||
if(substr($screen_name, 0, strlen("id")) === "id") {
|
|
||||||
return (object) [
|
public function resolveScreenName(string $screen_name): object
|
||||||
"object_id" => (int) substr($screen_name, strlen("id")),
|
{
|
||||||
"type" => "user"
|
if (\Chandler\MVC\Routing\Router::i()->getMatchingRoute("/$screen_name")[0]->presenter !== "UnknownTextRouteStrategy") {
|
||||||
];
|
if (substr($screen_name, 0, strlen("id")) === "id") {
|
||||||
} else if(substr($screen_name, 0, strlen("club")) === "club") {
|
return (object) [
|
||||||
return (object) [
|
"object_id" => (int) substr($screen_name, strlen("id")),
|
||||||
"object_id" => (int) substr($screen_name, strlen("club")),
|
"type" => "user",
|
||||||
"type" => "group"
|
];
|
||||||
];
|
} elseif (substr($screen_name, 0, strlen("club")) === "club") {
|
||||||
} else $this->fail(104, "Not found");
|
return (object) [
|
||||||
} else {
|
"object_id" => (int) substr($screen_name, strlen("club")),
|
||||||
$user = (new Users)->getByShortURL($screen_name);
|
"type" => "group",
|
||||||
if($user) {
|
];
|
||||||
return (object) [
|
} else {
|
||||||
"object_id" => $user->getId(),
|
$this->fail(104, "Not found");
|
||||||
"type" => "user"
|
}
|
||||||
];
|
} else {
|
||||||
}
|
$user = (new Users())->getByShortURL($screen_name);
|
||||||
|
if ($user) {
|
||||||
$club = (new Clubs)->getByShortURL($screen_name);
|
return (object) [
|
||||||
if($club) {
|
"object_id" => $user->getId(),
|
||||||
return (object) [
|
"type" => "user",
|
||||||
"object_id" => $club->getId(),
|
];
|
||||||
"type" => "group"
|
}
|
||||||
];
|
|
||||||
}
|
$club = (new Clubs())->getByShortURL($screen_name);
|
||||||
|
if ($club) {
|
||||||
$this->fail(104, "Not found");
|
return (object) [
|
||||||
}
|
"object_id" => $club->getId(),
|
||||||
}
|
"type" => "group",
|
||||||
|
];
|
||||||
function resolveGuid(string $guid): object
|
}
|
||||||
{
|
|
||||||
$user = (new Users)->getByChandlerUserId($guid);
|
$this->fail(104, "Not found");
|
||||||
if (is_null($user))
|
}
|
||||||
$this->fail(104, "Not found");
|
}
|
||||||
|
|
||||||
return $user->toVkApiStruct($this->getUser());
|
public function resolveGuid(string $guid): object
|
||||||
}
|
{
|
||||||
}
|
$user = (new Users())->getByChandlerUserId($guid);
|
||||||
|
if (is_null($user)) {
|
||||||
|
$this->fail(104, "Not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $user->toVkApiStruct($this->getUser());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use openvk\VKAPI\Exceptions\APIErrorException;
|
use openvk\VKAPI\Exceptions\APIErrorException;
|
||||||
use openvk\Web\Models\Entities\IP;
|
use openvk\Web\Models\Entities\IP;
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
|
@ -9,50 +13,51 @@ abstract class VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
protected $user;
|
protected $user;
|
||||||
protected $platform;
|
protected $platform;
|
||||||
|
|
||||||
function __construct(?User $user = NULL, ?string $platform = NULL)
|
public function __construct(?User $user = null, ?string $platform = null)
|
||||||
{
|
{
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
$this->platform = $platform;
|
$this->platform = $platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function fail(int $code, string $message): void
|
protected function fail(int $code, string $message): void
|
||||||
{
|
{
|
||||||
throw new APIErrorException($message, $code);
|
throw new APIErrorException($message, $code);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getUser(): ?User
|
protected function getUser(): ?User
|
||||||
{
|
{
|
||||||
return $this->user;
|
return $this->user;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPlatform(): ?string
|
protected function getPlatform(): ?string
|
||||||
{
|
{
|
||||||
return $this->platform ?? "";
|
return $this->platform ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function userAuthorized(): bool
|
protected function userAuthorized(): bool
|
||||||
{
|
{
|
||||||
return !is_null($this->getUser());
|
return !is_null($this->getUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function requireUser(): void
|
protected function requireUser(): void
|
||||||
{
|
{
|
||||||
if(!$this->userAuthorized())
|
if (!$this->userAuthorized()) {
|
||||||
$this->fail(5, "User authorization failed: no access_token passed.");
|
$this->fail(5, "User authorization failed: no access_token passed.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function willExecuteWriteAction(): void
|
protected function willExecuteWriteAction(): void
|
||||||
{
|
{
|
||||||
$ip = (new IPs)->get(CONNECTING_IP);
|
$ip = (new IPs())->get(CONNECTING_IP);
|
||||||
$res = $ip->rateLimit();
|
$res = $ip->rateLimit();
|
||||||
|
|
||||||
if(!($res === IP::RL_RESET || $res === IP::RL_CANEXEC)) {
|
if (!($res === IP::RL_RESET || $res === IP::RL_CANEXEC)) {
|
||||||
if($res === IP::RL_BANNED && OPENVK_ROOT_CONF["openvk"]["preferences"]["security"]["rateLimits"]["autoban"]) {
|
if ($res === IP::RL_BANNED && OPENVK_ROOT_CONF["openvk"]["preferences"]["security"]["rateLimits"]["autoban"]) {
|
||||||
$this->user->ban("User account has been suspended for breaking API terms of service", false);
|
$this->user->ban("User account has been suspended for breaking API terms of service", false);
|
||||||
$this->fail(18, "User account has been suspended due to repeated violation of API rate limits.");
|
$this->fail(18, "User account has been suspended due to repeated violation of API rate limits.");
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->fail(29, "You have been rate limited.");
|
$this->fail(29, "You have been rate limited.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
use openvk\Web\Models\Repositories\Users as UsersRepo;
|
||||||
use openvk\Web\Models\Entities\Club;
|
use openvk\Web\Models\Entities\Club;
|
||||||
|
@ -11,48 +15,49 @@ use openvk\Web\Models\Repositories\Comments as CommentsRepo;
|
||||||
|
|
||||||
final class Video extends VKAPIRequestHandler
|
final class Video extends VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
function get(int $owner_id = 0, string $videos = "", string $fields = "", int $offset = 0, int $count = 30, int $extended = 0): object
|
public function get(int $owner_id = 0, string $videos = "", string $fields = "", int $offset = 0, int $count = 30, int $extended = 0): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
if(!empty($videos)) {
|
if (!empty($videos)) {
|
||||||
$vids = explode(',', $videos);
|
$vids = explode(',', $videos);
|
||||||
$profiles = [];
|
$profiles = [];
|
||||||
$groups = [];
|
$groups = [];
|
||||||
foreach($vids as $vid) {
|
foreach ($vids as $vid) {
|
||||||
$id = explode("_", $vid);
|
$id = explode("_", $vid);
|
||||||
$items = [];
|
$items = [];
|
||||||
|
|
||||||
$video = (new VideosRepo)->getByOwnerAndVID(intval($id[0]), intval($id[1]));
|
$video = (new VideosRepo())->getByOwnerAndVID(intval($id[0]), intval($id[1]));
|
||||||
if($video && !$video->isDeleted()) {
|
if ($video && !$video->isDeleted()) {
|
||||||
$out_video = $video->getApiStructure($this->getUser())->video;
|
$out_video = $video->getApiStructure($this->getUser())->video;
|
||||||
$items[] = $out_video;
|
$items[] = $out_video;
|
||||||
if($out_video['owner_id']) {
|
if ($out_video['owner_id']) {
|
||||||
if($out_video['owner_id'] > 0)
|
if ($out_video['owner_id'] > 0) {
|
||||||
$profiles[] = $out_video['owner_id'];
|
$profiles[] = $out_video['owner_id'];
|
||||||
else
|
} else {
|
||||||
$groups[] = abs($out_video['owner_id']);
|
$groups[] = abs($out_video['owner_id']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($extended == 1) {
|
if ($extended == 1) {
|
||||||
$profiles = array_unique($profiles);
|
$profiles = array_unique($profiles);
|
||||||
$groups = array_unique($groups);
|
$groups = array_unique($groups);
|
||||||
|
|
||||||
$profilesFormatted = [];
|
$profilesFormatted = [];
|
||||||
$groupsFormatted = [];
|
$groupsFormatted = [];
|
||||||
|
|
||||||
foreach($profiles as $prof) {
|
foreach ($profiles as $prof) {
|
||||||
$profile = (new UsersRepo)->get($prof);
|
$profile = (new UsersRepo())->get($prof);
|
||||||
$profilesFormatted[] = $profile->toVkApiStruct($this->getUser(), $fields);
|
$profilesFormatted[] = $profile->toVkApiStruct($this->getUser(), $fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($groups as $gr) {
|
foreach ($groups as $gr) {
|
||||||
$group = (new ClubsRepo)->get($gr);
|
$group = (new ClubsRepo())->get($gr);
|
||||||
$groupsFormatted[] = $group->toVkApiStruct($this->getUser(), $fields);
|
$groupsFormatted[] = $group->toVkApiStruct($this->getUser(), $fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
"count" => sizeof($items),
|
"count" => sizeof($items),
|
||||||
"items" => $items,
|
"items" => $items,
|
||||||
|
@ -60,57 +65,61 @@ final class Video extends VKAPIRequestHandler
|
||||||
"groups" => $groupsFormatted,
|
"groups" => $groupsFormatted,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
"count" => count($items),
|
"count" => count($items),
|
||||||
"items" => $items
|
"items" => $items,
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
if ($owner_id > 0)
|
if ($owner_id > 0) {
|
||||||
$user = (new UsersRepo)->get($owner_id);
|
$user = (new UsersRepo())->get($owner_id);
|
||||||
else
|
} else {
|
||||||
$this->fail(1, "Not implemented");
|
$this->fail(1, "Not implemented");
|
||||||
|
}
|
||||||
if(!$user || $user->isDeleted())
|
|
||||||
|
if (!$user || $user->isDeleted()) {
|
||||||
$this->fail(14, "Invalid user");
|
$this->fail(14, "Invalid user");
|
||||||
|
}
|
||||||
|
|
||||||
if(!$user->getPrivacyPermission('videos.read', $this->getUser()))
|
if (!$user->getPrivacyPermission('videos.read', $this->getUser())) {
|
||||||
$this->fail(21, "This user chose to hide his videos.");
|
$this->fail(21, "This user chose to hide his videos.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$videos = (new VideosRepo())->getByUserLimit($user, $offset, $count);
|
||||||
|
$videosCount = (new VideosRepo())->getUserVideosCount($user);
|
||||||
|
|
||||||
$videos = (new VideosRepo)->getByUserLimit($user, $offset, $count);
|
|
||||||
$videosCount = (new VideosRepo)->getUserVideosCount($user);
|
|
||||||
|
|
||||||
$items = [];
|
$items = [];
|
||||||
$profiles = [];
|
$profiles = [];
|
||||||
$groups = [];
|
$groups = [];
|
||||||
foreach($videos as $video) {
|
foreach ($videos as $video) {
|
||||||
$video = $video->getApiStructure($this->getUser())->video;
|
$video = $video->getApiStructure($this->getUser())->video;
|
||||||
$items[] = $video;
|
$items[] = $video;
|
||||||
if($video['owner_id']) {
|
if ($video['owner_id']) {
|
||||||
if($video['owner_id'] > 0)
|
if ($video['owner_id'] > 0) {
|
||||||
$profiles[] = $video['owner_id'];
|
$profiles[] = $video['owner_id'];
|
||||||
else
|
} else {
|
||||||
$groups[] = abs($video['owner_id']);
|
$groups[] = abs($video['owner_id']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($extended == 1) {
|
if ($extended == 1) {
|
||||||
$profiles = array_unique($profiles);
|
$profiles = array_unique($profiles);
|
||||||
$groups = array_unique($groups);
|
$groups = array_unique($groups);
|
||||||
|
|
||||||
$profilesFormatted = [];
|
$profilesFormatted = [];
|
||||||
$groupsFormatted = [];
|
$groupsFormatted = [];
|
||||||
|
|
||||||
foreach($profiles as $prof) {
|
foreach ($profiles as $prof) {
|
||||||
$profile = (new UsersRepo)->get($prof);
|
$profile = (new UsersRepo())->get($prof);
|
||||||
$profilesFormatted[] = $profile->toVkApiStruct($this->getUser(), $fields);
|
$profilesFormatted[] = $profile->toVkApiStruct($this->getUser(), $fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($groups as $gr) {
|
foreach ($groups as $gr) {
|
||||||
$group = (new ClubsRepo)->get($gr);
|
$group = (new ClubsRepo())->get($gr);
|
||||||
$groupsFormatted[] = $group->toVkApiStruct($this->getUser(), $fields);
|
$groupsFormatted[] = $group->toVkApiStruct($this->getUser(), $fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
"count" => $videosCount,
|
"count" => $videosCount,
|
||||||
"items" => $items,
|
"items" => $items,
|
||||||
|
@ -118,54 +127,55 @@ final class Video extends VKAPIRequestHandler
|
||||||
"groups" => $groupsFormatted,
|
"groups" => $groupsFormatted,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
"count" => $videosCount,
|
"count" => $videosCount,
|
||||||
"items" => $items
|
"items" => $items,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function search(string $q = '', int $sort = 0, int $offset = 0, int $count = 10, bool $extended = false, string $fields = ''): object
|
public function search(string $q = '', int $sort = 0, int $offset = 0, int $count = 10, bool $extended = false, string $fields = ''): object
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
$params = [];
|
$params = [];
|
||||||
$db_sort = ['type' => 'id', 'invert' => false];
|
$db_sort = ['type' => 'id', 'invert' => false];
|
||||||
$videos = (new VideosRepo)->find($q, $params, $db_sort);
|
$videos = (new VideosRepo())->find($q, $params, $db_sort);
|
||||||
$items = iterator_to_array($videos->offsetLimit($offset, $count));
|
$items = iterator_to_array($videos->offsetLimit($offset, $count));
|
||||||
$count = $videos->size();
|
$count = $videos->size();
|
||||||
|
|
||||||
$return_items = [];
|
$return_items = [];
|
||||||
$profiles = [];
|
$profiles = [];
|
||||||
$groups = [];
|
$groups = [];
|
||||||
foreach($items as $item) {
|
foreach ($items as $item) {
|
||||||
$return_item = $item->getApiStructure($this->getUser());
|
$return_item = $item->getApiStructure($this->getUser());
|
||||||
$return_item = $return_item->video;
|
$return_item = $return_item->video;
|
||||||
$return_items[] = $return_item;
|
$return_items[] = $return_item;
|
||||||
|
|
||||||
if($return_item['owner_id']) {
|
if ($return_item['owner_id']) {
|
||||||
if($return_item['owner_id'] > 0)
|
if ($return_item['owner_id'] > 0) {
|
||||||
$profiles[] = $return_item['owner_id'];
|
$profiles[] = $return_item['owner_id'];
|
||||||
else
|
} else {
|
||||||
$groups[] = abs($return_item['owner_id']);
|
$groups[] = abs($return_item['owner_id']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($extended) {
|
if ($extended) {
|
||||||
$profiles = array_unique($profiles);
|
$profiles = array_unique($profiles);
|
||||||
$groups = array_unique($groups);
|
$groups = array_unique($groups);
|
||||||
|
|
||||||
$profilesFormatted = [];
|
$profilesFormatted = [];
|
||||||
$groupsFormatted = [];
|
$groupsFormatted = [];
|
||||||
|
|
||||||
foreach($profiles as $prof) {
|
foreach ($profiles as $prof) {
|
||||||
$profile = (new UsersRepo)->get($prof);
|
$profile = (new UsersRepo())->get($prof);
|
||||||
$profilesFormatted[] = $profile->toVkApiStruct($this->getUser(), $fields);
|
$profilesFormatted[] = $profile->toVkApiStruct($this->getUser(), $fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($groups as $gr) {
|
foreach ($groups as $gr) {
|
||||||
$group = (new ClubsRepo)->get($gr);
|
$group = (new ClubsRepo())->get($gr);
|
||||||
$groupsFormatted[] = $group->toVkApiStruct($this->getUser(), $fields);
|
$groupsFormatted[] = $group->toVkApiStruct($this->getUser(), $fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,7 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Structures;
|
namespace openvk\VKAPI\Structures;
|
||||||
|
|
||||||
final class Conversation
|
final class Conversation
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\VKAPI\Structures;
|
namespace openvk\VKAPI\Structures;
|
||||||
|
|
||||||
final class Message
|
final class Message
|
||||||
|
@ -17,5 +20,5 @@ final class Message
|
||||||
public $emoji;
|
public $emoji;
|
||||||
public $important = true;
|
public $important = true;
|
||||||
public $deleted = 0;
|
public $deleted = 0;
|
||||||
public $random_id = NULL;
|
public $random_id = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Events;
|
namespace openvk\Web\Events;
|
||||||
|
|
||||||
interface ILPEmitable
|
interface ILPEmitable
|
||||||
{
|
{
|
||||||
function getLongPoolSummary(): object;
|
public function getLongPoolSummary(): object;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,37 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Events;
|
namespace openvk\Web\Events;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\Message;
|
use openvk\Web\Models\Entities\Message;
|
||||||
use openvk\Web\Models\Repositories\Messages;
|
use openvk\Web\Models\Repositories\Messages;
|
||||||
|
|
||||||
class NewMessageEvent implements ILPEmitable
|
class NewMessageEvent implements ILPEmitable
|
||||||
{
|
{
|
||||||
protected $payload;
|
protected $payload;
|
||||||
|
|
||||||
function __construct(Message $message)
|
public function __construct(Message $message)
|
||||||
{
|
{
|
||||||
$this->payload = $message->simplify();
|
$this->payload = $message->simplify();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLongPoolSummary(): object
|
public function getLongPoolSummary(): object
|
||||||
{
|
{
|
||||||
return (object) [
|
return (object) [
|
||||||
"type" => "newMessage",
|
"type" => "newMessage",
|
||||||
"message" => $this->payload,
|
"message" => $this->payload,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVKAPISummary(int $userId): array
|
public function getVKAPISummary(int $userId): array
|
||||||
{
|
{
|
||||||
$msg = (new Messages)->get($this->payload["uuid"]);
|
$msg = (new Messages())->get($this->payload["uuid"]);
|
||||||
$peer = $msg->getSender()->getId();
|
$peer = $msg->getSender()->getId();
|
||||||
if($peer === $userId)
|
if ($peer === $userId) {
|
||||||
$peer = $msg->getRecipient()->getId();
|
$peer = $msg->getRecipient()->getId();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Source:
|
* Source:
|
||||||
* https://github.com/danyadev/longpoll-doc
|
* https://github.com/danyadev/longpoll-doc
|
||||||
|
@ -43,7 +48,7 @@ class NewMessageEvent implements ILPEmitable
|
||||||
[], # empty attachments
|
[], # empty attachments
|
||||||
$msg->getId() << 2, # id as random_id
|
$msg->getId() << 2, # id as random_id
|
||||||
$peer, # conversation id
|
$peer, # conversation id
|
||||||
0 # not edited yet
|
0, # not edited yet
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Models\Repositories\Users;
|
use openvk\Web\Models\Repositories\Users;
|
||||||
use Nette\InvalidStateException as ISE;
|
use Nette\InvalidStateException as ISE;
|
||||||
|
@ -7,52 +11,53 @@ use Nette\InvalidStateException as ISE;
|
||||||
class APIToken extends RowModel
|
class APIToken extends RowModel
|
||||||
{
|
{
|
||||||
protected $tableName = "api_tokens";
|
protected $tableName = "api_tokens";
|
||||||
|
|
||||||
function getUser(): User
|
public function getUser(): User
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getRecord()->user);
|
return (new Users())->get($this->getRecord()->user);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSecret(): string
|
public function getSecret(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->secret;
|
return $this->getRecord()->secret;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFormattedToken(): string
|
public function getFormattedToken(): string
|
||||||
{
|
{
|
||||||
return $this->getId() . "-" . chunk_split($this->getSecret(), 8, "-") . "jill";
|
return $this->getId() . "-" . chunk_split($this->getSecret(), 8, "-") . "jill";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPlatform(): ?string
|
public function getPlatform(): ?string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->platform;
|
return $this->getRecord()->platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isRevoked(): bool
|
public function isRevoked(): bool
|
||||||
{
|
{
|
||||||
return $this->isDeleted();
|
return $this->isDeleted();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setUser(User $user): void
|
public function setUser(User $user): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("user", $user->getId());
|
$this->stateChanges("user", $user->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSecret(string $secret): void
|
public function setSecret(string $secret): void
|
||||||
{
|
{
|
||||||
throw new ISE("Setting secret manually is prohbited");
|
throw new ISE("Setting secret manually is prohbited");
|
||||||
}
|
}
|
||||||
|
|
||||||
function revoke(): void
|
public function revoke(): void
|
||||||
{
|
{
|
||||||
$this->delete();
|
$this->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
function save(?bool $log = false): void
|
public function save(?bool $log = false): void
|
||||||
{
|
{
|
||||||
if(is_null($this->getRecord()))
|
if (is_null($this->getRecord())) {
|
||||||
$this->stateChanges("secret", bin2hex(openssl_random_pseudo_bytes(36)));
|
$this->stateChanges("secret", bin2hex(openssl_random_pseudo_bytes(36)));
|
||||||
|
}
|
||||||
|
|
||||||
parent::save();
|
parent::save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,88 +1,94 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Models\Repositories\Photos;
|
use openvk\Web\Models\Repositories\Photos;
|
||||||
|
|
||||||
class Album extends MediaCollection
|
class Album extends MediaCollection
|
||||||
{
|
{
|
||||||
const SPECIAL_AVATARS = 16;
|
public const SPECIAL_AVATARS = 16;
|
||||||
const SPECIAL_WALL = 32;
|
public const SPECIAL_WALL = 32;
|
||||||
|
|
||||||
protected $tableName = "albums";
|
protected $tableName = "albums";
|
||||||
protected $relTableName = "album_relations";
|
protected $relTableName = "album_relations";
|
||||||
protected $entityTableName = "photos";
|
protected $entityTableName = "photos";
|
||||||
protected $entityClassName = 'openvk\Web\Models\Entities\Photo';
|
protected $entityClassName = 'openvk\Web\Models\Entities\Photo';
|
||||||
|
|
||||||
protected $specialNames = [
|
protected $specialNames = [
|
||||||
16 => "_avatar_album",
|
16 => "_avatar_album",
|
||||||
32 => "_wall_album",
|
32 => "_wall_album",
|
||||||
64 => "_saved_photos_album",
|
64 => "_saved_photos_album",
|
||||||
];
|
];
|
||||||
|
|
||||||
function getCoverURL(): ?string
|
public function getCoverURL(): ?string
|
||||||
{
|
{
|
||||||
$coverPhoto = $this->getCoverPhoto();
|
$coverPhoto = $this->getCoverPhoto();
|
||||||
if(!$coverPhoto)
|
if (!$coverPhoto) {
|
||||||
return "/assets/packages/static/openvk/img/camera_200.png";
|
return "/assets/packages/static/openvk/img/camera_200.png";
|
||||||
|
}
|
||||||
|
|
||||||
return $coverPhoto->getURL();
|
return $coverPhoto->getURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCoverPhoto(): ?Photo
|
public function getCoverPhoto(): ?Photo
|
||||||
{
|
{
|
||||||
$cover = $this->getRecord()->cover_photo;
|
$cover = $this->getRecord()->cover_photo;
|
||||||
if(!$cover) {
|
if (!$cover) {
|
||||||
$photos = iterator_to_array($this->getPhotos(1, 1));
|
$photos = iterator_to_array($this->getPhotos(1, 1));
|
||||||
$photo = $photos[0] ?? NULL;
|
$photo = $photos[0] ?? null;
|
||||||
if(!$photo || $photo->isDeleted())
|
if (!$photo || $photo->isDeleted()) {
|
||||||
return NULL;
|
return null;
|
||||||
else
|
} else {
|
||||||
return $photo;
|
return $photo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (new Photos)->get($cover);
|
return (new Photos())->get($cover);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPhotos(int $page = 1, ?int $perPage = NULL): \Traversable
|
public function getPhotos(int $page = 1, ?int $perPage = null): \Traversable
|
||||||
{
|
{
|
||||||
return $this->fetch($page, $perPage);
|
return $this->fetch($page, $perPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPhotosCount(): int
|
public function getPhotosCount(): int
|
||||||
{
|
{
|
||||||
return $this->size();
|
return $this->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
function addPhoto(Photo $photo): void
|
public function addPhoto(Photo $photo): void
|
||||||
{
|
{
|
||||||
$this->add($photo);
|
$this->add($photo);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removePhoto(Photo $photo): void
|
public function removePhoto(Photo $photo): void
|
||||||
{
|
{
|
||||||
$this->remove($photo);
|
$this->remove($photo);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasPhoto(Photo $photo): bool
|
public function hasPhoto(Photo $photo): bool
|
||||||
{
|
{
|
||||||
return $this->has($photo);
|
return $this->has($photo);
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBeViewedBy(?User $user = NULL): bool
|
public function canBeViewedBy(?User $user = null): bool
|
||||||
{
|
{
|
||||||
if($this->isDeleted()) {
|
if ($this->isDeleted()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$owner = $this->getOwner();
|
$owner = $this->getOwner();
|
||||||
|
|
||||||
if(get_class($owner) == "openvk\\Web\\Models\\Entities\\User") {
|
if (get_class($owner) == "openvk\\Web\\Models\\Entities\\User") {
|
||||||
return $owner->canBeViewedBy($user) && $owner->getPrivacyPermission('photos.read', $user);
|
return $owner->canBeViewedBy($user) && $owner->getPrivacyPermission('photos.read', $user);
|
||||||
} else {
|
} else {
|
||||||
return $owner->canBeViewedBy($user);
|
return $owner->canBeViewedBy($user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toVkApiStruct(?User $user = NULL, bool $need_covers = false, bool $photo_sizes = false): object
|
public function toVkApiStruct(?User $user = null, bool $need_covers = false, bool $photo_sizes = false): object
|
||||||
{
|
{
|
||||||
$res = (object) [];
|
$res = (object) [];
|
||||||
|
|
||||||
|
@ -93,17 +99,17 @@ class Album extends MediaCollection
|
||||||
$res->title = $this->getName();
|
$res->title = $this->getName();
|
||||||
$res->description = $this->getDescription();
|
$res->description = $this->getDescription();
|
||||||
$res->created = $this->getCreationTime()->timestamp();
|
$res->created = $this->getCreationTime()->timestamp();
|
||||||
$res->updated = $this->getEditTime() ? $this->getEditTime()->timestamp() : NULL;
|
$res->updated = $this->getEditTime() ? $this->getEditTime()->timestamp() : null;
|
||||||
$res->size = $this->size();
|
$res->size = $this->size();
|
||||||
$res->privacy_comment = 1;
|
$res->privacy_comment = 1;
|
||||||
$res->upload_by_admins_only = 1;
|
$res->upload_by_admins_only = 1;
|
||||||
$res->comments_disabled = 0;
|
$res->comments_disabled = 0;
|
||||||
$res->can_upload = $this->canBeModifiedBy($user); # thisUser недоступен в entities
|
$res->can_upload = $this->canBeModifiedBy($user); # thisUser недоступен в entities
|
||||||
if($need_covers) {
|
if ($need_covers) {
|
||||||
$res->thumb_src = $this->getCoverURL();
|
$res->thumb_src = $this->getCoverURL();
|
||||||
|
|
||||||
if($photo_sizes) {
|
if ($photo_sizes) {
|
||||||
$res->sizes = !is_null($this->getCoverPhoto()) ? $this->getCoverPhoto()->getVkApiSizes() : NULL;
|
$res->sizes = !is_null($this->getCoverPhoto()) ? $this->getCoverPhoto()->getVkApiSizes() : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
|
@ -8,27 +11,28 @@ use openvk\Web\Models\Repositories\{Users, Clubs};
|
||||||
class Alias extends RowModel
|
class Alias extends RowModel
|
||||||
{
|
{
|
||||||
protected $tableName = "aliases";
|
protected $tableName = "aliases";
|
||||||
|
|
||||||
function getOwnerId(): int
|
public function getOwnerId(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->owner_id;
|
return $this->getRecord()->owner_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getType(): string
|
public function getType(): string
|
||||||
{
|
{
|
||||||
if ($this->getOwnerId() < 0)
|
if ($this->getOwnerId() < 0) {
|
||||||
return "club";
|
return "club";
|
||||||
|
}
|
||||||
|
|
||||||
return "user";
|
return "user";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUser(): ?User
|
public function getUser(): ?User
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getOwnerId());
|
return (new Users())->get($this->getOwnerId());
|
||||||
}
|
}
|
||||||
|
|
||||||
function getClub(): ?Club
|
public function getClub(): ?Club
|
||||||
{
|
{
|
||||||
return (new Clubs)->get($this->getOwnerId() * -1);
|
return (new Clubs())->get($this->getOwnerId() * -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use Chandler\Database\DatabaseConnection;
|
use Chandler\Database\DatabaseConnection;
|
||||||
use Nette\Utils\Image;
|
use Nette\Utils\Image;
|
||||||
use Nette\Utils\UnknownImageFileException;
|
use Nette\Utils\UnknownImageFileException;
|
||||||
|
@ -10,8 +14,8 @@ use openvk\Web\Models\RowModel;
|
||||||
class Application extends RowModel
|
class Application extends RowModel
|
||||||
{
|
{
|
||||||
protected $tableName = "apps";
|
protected $tableName = "apps";
|
||||||
|
|
||||||
const PERMS = [
|
public const PERMS = [
|
||||||
"notify",
|
"notify",
|
||||||
"friends",
|
"friends",
|
||||||
"photos",
|
"photos",
|
||||||
|
@ -31,44 +35,46 @@ class Application extends RowModel
|
||||||
"email",
|
"email",
|
||||||
"market",
|
"market",
|
||||||
];
|
];
|
||||||
|
|
||||||
private function getAvatarsDir(): string
|
private function getAvatarsDir(): string
|
||||||
{
|
{
|
||||||
$uploadSettings = OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"];
|
$uploadSettings = OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"];
|
||||||
if($uploadSettings["mode"] === "server" && $uploadSettings["server"]["kind"] === "cdn")
|
if ($uploadSettings["mode"] === "server" && $uploadSettings["server"]["kind"] === "cdn") {
|
||||||
return $uploadSettings["server"]["directory"];
|
return $uploadSettings["server"]["directory"];
|
||||||
else
|
} else {
|
||||||
return OPENVK_ROOT . "/storage/";
|
return OPENVK_ROOT . "/storage/";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getId(): int
|
public function getId(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->id;
|
return $this->getRecord()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOwner(): User
|
public function getOwner(): User
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getRecord()->owner);
|
return (new Users())->get($this->getRecord()->owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getName(): string
|
public function getName(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->name;
|
return $this->getRecord()->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDescription(): string
|
public function getDescription(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->description;
|
return $this->getRecord()->description;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAvatarUrl(): string
|
public function getAvatarUrl(): string
|
||||||
{
|
{
|
||||||
$serverUrl = ovk_scheme(true) . $_SERVER["HTTP_HOST"];
|
$serverUrl = ovk_scheme(true) . $_SERVER["HTTP_HOST"];
|
||||||
if(is_null($this->getRecord()->avatar_hash))
|
if (is_null($this->getRecord()->avatar_hash)) {
|
||||||
return "$serverUrl/assets/packages/static/openvk/img/camera_200.png";
|
return "$serverUrl/assets/packages/static/openvk/img/camera_200.png";
|
||||||
|
}
|
||||||
|
|
||||||
$hash = $this->getRecord()->avatar_hash;
|
$hash = $this->getRecord()->avatar_hash;
|
||||||
switch(OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["mode"]) {
|
switch (OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["mode"]) {
|
||||||
default:
|
default:
|
||||||
case "default":
|
case "default":
|
||||||
case "basic":
|
case "basic":
|
||||||
|
@ -85,155 +91,168 @@ class Application extends RowModel
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNote(): ?Note
|
public function getNote(): ?Note
|
||||||
{
|
{
|
||||||
if(!$this->getRecord()->news)
|
if (!$this->getRecord()->news) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
return (new Notes)->get($this->getRecord()->news);
|
|
||||||
|
return (new Notes())->get($this->getRecord()->news);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNoteLink(): string
|
public function getNoteLink(): string
|
||||||
{
|
{
|
||||||
$note = $this->getNote();
|
$note = $this->getNote();
|
||||||
if(!$note)
|
if (!$note) {
|
||||||
return "";
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
return ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/note" . $note->getPrettyId();
|
return ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/note" . $note->getPrettyId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBalance(): float
|
public function getBalance(): float
|
||||||
{
|
{
|
||||||
return $this->getRecord()->coins;
|
return $this->getRecord()->coins;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getURL(): string
|
public function getURL(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->address;
|
return $this->getRecord()->address;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOrigin(): string
|
public function getOrigin(): string
|
||||||
{
|
{
|
||||||
$parsed = parse_url($this->getURL());
|
$parsed = parse_url($this->getURL());
|
||||||
|
|
||||||
return (
|
return (
|
||||||
($parsed["scheme"] ?? "https") . "://"
|
($parsed["scheme"] ?? "https") . "://"
|
||||||
. ($parsed["host"] ?? "127.0.0.1") . ":"
|
. ($parsed["host"] ?? "127.0.0.1") . ":"
|
||||||
. ($parsed["port"] ?? "443")
|
. ($parsed["port"] ?? "443")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUsersCount(): int
|
public function getUsersCount(): int
|
||||||
{
|
{
|
||||||
$cx = DatabaseConnection::i()->getContext();
|
$cx = DatabaseConnection::i()->getContext();
|
||||||
return sizeof($cx->table("app_users")->where("app", $this->getId()));
|
return sizeof($cx->table("app_users")->where("app", $this->getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInstallationEntry(User $user): ?array
|
public function getInstallationEntry(User $user): ?array
|
||||||
{
|
{
|
||||||
$cx = DatabaseConnection::i()->getContext();
|
$cx = DatabaseConnection::i()->getContext();
|
||||||
$entry = $cx->table("app_users")->where([
|
$entry = $cx->table("app_users")->where([
|
||||||
"app" => $this->getId(),
|
"app" => $this->getId(),
|
||||||
"user" => $user->getId(),
|
"user" => $user->getId(),
|
||||||
])->fetch();
|
])->fetch();
|
||||||
|
|
||||||
if(!$entry)
|
if (!$entry) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return $entry->toArray();
|
return $entry->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPermissions(User $user): array
|
public function getPermissions(User $user): array
|
||||||
{
|
{
|
||||||
$permMask = 0;
|
$permMask = 0;
|
||||||
$installInfo = $this->getInstallationEntry($user);
|
$installInfo = $this->getInstallationEntry($user);
|
||||||
if(!$installInfo)
|
if (!$installInfo) {
|
||||||
$this->install($user);
|
$this->install($user);
|
||||||
else
|
} else {
|
||||||
$permMask = $installInfo["access"];
|
$permMask = $installInfo["access"];
|
||||||
|
|
||||||
$res = [];
|
|
||||||
for($i = 0; $i < sizeof(self::PERMS); $i++) {
|
|
||||||
$checkVal = 1 << $i;
|
|
||||||
if(($permMask & $checkVal) > 0)
|
|
||||||
$res[] = self::PERMS[$i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$res = [];
|
||||||
|
for ($i = 0; $i < sizeof(self::PERMS); $i++) {
|
||||||
|
$checkVal = 1 << $i;
|
||||||
|
if (($permMask & $checkVal) > 0) {
|
||||||
|
$res[] = self::PERMS[$i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isInstalledBy(User $user): bool
|
public function isInstalledBy(User $user): bool
|
||||||
{
|
{
|
||||||
return !is_null($this->getInstallationEntry($user));
|
return !is_null($this->getInstallationEntry($user));
|
||||||
}
|
}
|
||||||
|
|
||||||
function setNoteLink(?string $link): bool
|
public function setNoteLink(?string $link): bool
|
||||||
{
|
{
|
||||||
if(!$link) {
|
if (!$link) {
|
||||||
$this->stateChanges("news", NULL);
|
$this->stateChanges("news", null);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
preg_match("%note([0-9]+)_([0-9]+)$%", $link, $matches);
|
preg_match("%note([0-9]+)_([0-9]+)$%", $link, $matches);
|
||||||
if(sizeof($matches) != 3)
|
if (sizeof($matches) != 3) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$owner = is_null($this->getRecord()) ? $this->changes["owner"] : $this->getRecord()->owner;
|
$owner = is_null($this->getRecord()) ? $this->changes["owner"] : $this->getRecord()->owner;
|
||||||
[, $ownerId, $vid] = $matches;
|
[, $ownerId, $vid] = $matches;
|
||||||
if($ownerId != $owner)
|
if ($ownerId != $owner) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
$note = (new Notes)->getNoteById((int) $ownerId, (int) $vid);
|
|
||||||
if(!$note)
|
$note = (new Notes())->getNoteById((int) $ownerId, (int) $vid);
|
||||||
|
if (!$note) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$this->stateChanges("news", $note->getId());
|
$this->stateChanges("news", $note->getId());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAvatar(array $file): int
|
public function setAvatar(array $file): int
|
||||||
{
|
{
|
||||||
if($file["error"] !== UPLOAD_ERR_OK)
|
if ($file["error"] !== UPLOAD_ERR_OK) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$image = Image::fromFile($file["tmp_name"]);
|
$image = Image::fromFile($file["tmp_name"]);
|
||||||
} catch (UnknownImageFileException $e) {
|
} catch (UnknownImageFileException $e) {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
$hash = hash_file("adler32", $file["tmp_name"]);
|
$hash = hash_file("adler32", $file["tmp_name"]);
|
||||||
if(!is_dir($this->getAvatarsDir() . substr($hash, 0, 2)))
|
if (!is_dir($this->getAvatarsDir() . substr($hash, 0, 2))) {
|
||||||
if(!mkdir($this->getAvatarsDir() . substr($hash, 0, 2)))
|
if (!mkdir($this->getAvatarsDir() . substr($hash, 0, 2))) {
|
||||||
return -3;
|
return -3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$image->resize(140, 140, Image::STRETCH);
|
$image->resize(140, 140, Image::STRETCH);
|
||||||
$image->save($this->getAvatarsDir() . substr($hash, 0, 2) . "/$hash" . "_app_avatar.png");
|
$image->save($this->getAvatarsDir() . substr($hash, 0, 2) . "/$hash" . "_app_avatar.png");
|
||||||
|
|
||||||
$this->stateChanges("avatar_hash", $hash);
|
$this->stateChanges("avatar_hash", $hash);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPermission(User $user, string $perm, bool $enabled): bool
|
public function setPermission(User $user, string $perm, bool $enabled): bool
|
||||||
{
|
{
|
||||||
$permMask = 0;
|
$permMask = 0;
|
||||||
$installInfo = $this->getInstallationEntry($user);
|
$installInfo = $this->getInstallationEntry($user);
|
||||||
if(!$installInfo)
|
if (!$installInfo) {
|
||||||
$this->install($user);
|
$this->install($user);
|
||||||
else
|
} else {
|
||||||
$permMask = $installInfo["access"];
|
$permMask = $installInfo["access"];
|
||||||
|
}
|
||||||
|
|
||||||
$index = array_search($perm, self::PERMS);
|
$index = array_search($perm, self::PERMS);
|
||||||
if($index === false)
|
if ($index === false) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$permVal = 1 << $index;
|
$permVal = 1 << $index;
|
||||||
$permMask = $enabled ? ($permMask | $permVal) : ($permMask ^ $permVal);
|
$permMask = $enabled ? ($permMask | $permVal) : ($permMask ^ $permVal);
|
||||||
|
|
||||||
$cx = DatabaseConnection::i()->getContext();
|
$cx = DatabaseConnection::i()->getContext();
|
||||||
$cx->table("app_users")->where([
|
$cx->table("app_users")->where([
|
||||||
"app" => $this->getId(),
|
"app" => $this->getId(),
|
||||||
|
@ -241,30 +260,30 @@ class Application extends RowModel
|
||||||
])->update([
|
])->update([
|
||||||
"access" => $permMask,
|
"access" => $permMask,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isEnabled(): bool
|
public function isEnabled(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->enabled;
|
return (bool) $this->getRecord()->enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
function enable(): void
|
public function enable(): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("enabled", 1);
|
$this->stateChanges("enabled", 1);
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
function disable(): void
|
public function disable(): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("enabled", 0);
|
$this->stateChanges("enabled", 0);
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
function install(User $user): void
|
public function install(User $user): void
|
||||||
{
|
{
|
||||||
if(!$this->getInstallationEntry($user)) {
|
if (!$this->getInstallationEntry($user)) {
|
||||||
$cx = DatabaseConnection::i()->getContext();
|
$cx = DatabaseConnection::i()->getContext();
|
||||||
$cx->table("app_users")->insert([
|
$cx->table("app_users")->insert([
|
||||||
"app" => $this->getId(),
|
"app" => $this->getId(),
|
||||||
|
@ -272,8 +291,8 @@ class Application extends RowModel
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function uninstall(User $user): void
|
public function uninstall(User $user): void
|
||||||
{
|
{
|
||||||
$cx = DatabaseConnection::i()->getContext();
|
$cx = DatabaseConnection::i()->getContext();
|
||||||
$cx->table("app_users")->where([
|
$cx->table("app_users")->where([
|
||||||
|
@ -281,39 +300,42 @@ class Application extends RowModel
|
||||||
"user" => $user->getId(),
|
"user" => $user->getId(),
|
||||||
])->delete();
|
])->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
function addCoins(float $coins): float
|
public function addCoins(float $coins): float
|
||||||
{
|
{
|
||||||
$res = $this->getBalance() + $coins;
|
$res = $this->getBalance() + $coins;
|
||||||
$this->stateChanges("coins", $res);
|
$this->stateChanges("coins", $res);
|
||||||
$this->save();
|
$this->save();
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function withdrawCoins(): void
|
public function withdrawCoins(): void
|
||||||
{
|
{
|
||||||
$balance = $this->getBalance();
|
$balance = $this->getBalance();
|
||||||
$tax = ($balance / 100) * OPENVK_ROOT_CONF["openvk"]["preferences"]["apps"]["withdrawTax"];
|
$tax = ($balance / 100) * OPENVK_ROOT_CONF["openvk"]["preferences"]["apps"]["withdrawTax"];
|
||||||
|
|
||||||
$owner = $this->getOwner();
|
$owner = $this->getOwner();
|
||||||
$owner->setCoins($owner->getCoins() + ($balance - $tax));
|
$owner->setCoins($owner->getCoins() + ($balance - $tax));
|
||||||
$this->setCoins(0.0);
|
$this->setCoins(0.0);
|
||||||
$this->save();
|
$this->save();
|
||||||
$owner->save();
|
$owner->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete(bool $softly = true): void
|
public function delete(bool $softly = true): void
|
||||||
{
|
{
|
||||||
if($softly)
|
if ($softly) {
|
||||||
throw new \UnexpectedValueException("Can't delete apps softly."); // why
|
throw new \UnexpectedValueException("Can't delete apps softly.");
|
||||||
|
} // why
|
||||||
|
|
||||||
$cx = DatabaseConnection::i()->getContext();
|
$cx = DatabaseConnection::i()->getContext();
|
||||||
$cx->table("app_users")->where("app", $this->getId())->delete();
|
$cx->table("app_users")->where("app", $this->getId())->delete();
|
||||||
|
|
||||||
parent::delete(false);
|
parent::delete(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPublicationTime(): string
|
public function getPublicationTime(): string
|
||||||
{ return tr("recently"); }
|
{
|
||||||
}
|
return tr("recently");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,38 +1,42 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
|
|
||||||
abstract class Attachable extends RowModel
|
abstract class Attachable extends RowModel
|
||||||
{
|
{
|
||||||
function getId(): int
|
public function getId(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->id;
|
return $this->getRecord()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getParents(): \Traversable
|
public function getParents(): \Traversable
|
||||||
{
|
{
|
||||||
$sel = $this->getRecord()
|
$sel = $this->getRecord()
|
||||||
->related("attachments.attachable_id")
|
->related("attachments.attachable_id")
|
||||||
->where("attachments.attachable_type", get_class($this));
|
->where("attachments.attachable_type", get_class($this));
|
||||||
foreach($sel as $rel) {
|
foreach ($sel as $rel) {
|
||||||
$repoName = $rel->target_type . "s";
|
$repoName = $rel->target_type . "s";
|
||||||
$repoName = str_replace("Entities", "Repositories", $repoName);
|
$repoName = str_replace("Entities", "Repositories", $repoName);
|
||||||
$repo = new $repoName;
|
$repo = new $repoName();
|
||||||
|
|
||||||
yield $repo->get($rel->target_id);
|
yield $repo->get($rel->target_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes together with all references.
|
* Deletes together with all references.
|
||||||
*/
|
*/
|
||||||
function delete(bool $softly = true): void
|
public function delete(bool $softly = true): void
|
||||||
{
|
{
|
||||||
$this->getRecord()
|
$this->getRecord()
|
||||||
->related("attachments.attachable_id")
|
->related("attachments.attachable_id")
|
||||||
->where("attachments.attachable_type", get_class($this))
|
->where("attachments.attachable_type", get_class($this))
|
||||||
->delete();
|
->delete();
|
||||||
|
|
||||||
parent::delete();
|
parent::delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use Chandler\Database\DatabaseConnection;
|
use Chandler\Database\DatabaseConnection;
|
||||||
use openvk\Web\Util\Shell\Exceptions\UnknownCommandException;
|
use openvk\Web\Util\Shell\Exceptions\UnknownCommandException;
|
||||||
use openvk\Web\Util\Shell\Shell;
|
use openvk\Web\Util\Shell\Shell;
|
||||||
|
@ -16,12 +20,12 @@ class Audio extends Media
|
||||||
protected $fileExtension = "mpd";
|
protected $fileExtension = "mpd";
|
||||||
|
|
||||||
# Taken from winamp :D
|
# Taken from winamp :D
|
||||||
const genres = [
|
public const genres = [
|
||||||
'A Cappella', 'Abstract', 'Acid', 'Acid Jazz', 'Acid Punk', 'Acoustic', 'AlternRock', 'Alternative', 'Ambient', 'Anime', 'Art Rock', 'Audio Theatre', 'Audiobook', 'Avantgarde', 'Ballad', 'Baroque', 'Bass', 'Beat', 'Bebob', 'Bhangra', 'Big Band', 'Big Beat', 'Black Metal', 'Bluegrass', 'Blues', 'Booty Bass', 'Breakbeat', 'BritPop', 'Cabaret', 'Celtic', 'Chamber Music', 'Chanson', 'Chillout', 'Chorus', 'Christian Gangsta Rap', 'Christian Rap', 'Christian Rock', 'Classic Rock', 'Classical', 'Club', 'Club-House', 'Comedy', 'Contemporary Christian', 'Country', 'Crossover', 'Cult', 'Dance', 'Dance Hall', 'Darkwave', 'Death Metal', 'Disco', 'Downtempo', 'Dream', 'Drum & Bass', 'Drum Solo', 'Dub', 'Dubstep', 'Duet', 'EBM', 'Easy Listening', 'Eclectic', 'Electro', 'Electroclash', 'Electronic', 'Emo', 'Ethnic', 'Euro-House', 'Euro-Techno', 'Eurodance', 'Experimental', 'Fast Fusion', 'Folk', 'Folk-Rock', 'Folklore', 'Freestyle', 'Funk', 'Fusion', 'G-Funk', 'Game', 'Gangsta Rap', 'Garage', 'Garage Rock', 'Global', 'Goa', 'Gospel', 'Gothic', 'Gothic Rock', 'Grunge', 'Hard Rock', 'Hardcore', 'Heavy Metal', 'Hip-Hop', 'House', 'Humour', 'IDM', 'Illbient', 'Indie', 'Indie Rock', 'Industrial', 'Industro-Goth', 'Instrumental', 'Instrumental Pop', 'Instrumental Rock', 'JPop', 'Jam Band', 'Jazz', 'Jazz+Funk', 'Jungle', 'Krautrock', 'Latin', 'Leftfield', 'Lo-Fi', 'Lounge', 'Math Rock', 'Meditative', 'Merengue', 'Metal', 'Musical', 'National Folk', 'Native American', 'Negerpunk', 'Neoclassical', 'Neue Deutsche Welle', 'New Age', 'New Romantic', 'New Wave', 'Noise', 'Nu-Breakz', 'Oldies', 'Opera', 'Other', 'Podcast', 'Polka', 'Polsk Punk', 'Pop', 'Pop / Funk', 'Pop-Folk', 'Porn Groove', 'Post-Punk', 'Post-Rock', 'Power Ballad', 'Pranks', 'Primus', 'Progressive Rock', 'Psybient', 'Psychedelic', 'Psychedelic Rock', 'Psychobilly', 'Psytrance', 'Punk', 'Punk Rock', 'R&B', 'Rap', 'Rave', 'Reggae', 'Retro', 'Revival', 'Rhythmic Soul', 'Rock', 'Rock & Roll', 'Salsa', 'Samba', 'Satire', 'Shoegaze', 'Showtunes', 'Ska', 'Slow Jam', 'Slow Rock', 'Sonata', 'Soul', 'Sound Clip', 'Soundtrack', 'Southern Rock', 'Space', 'Space Rock', 'Speech', 'Swing', 'Symphonic Rock', 'Symphony', 'Synthpop', 'Tango', 'Techno', 'Techno-Industrial', 'Terror', 'Thrash Metal', 'Top 40', 'Touhou', 'Trailer', 'Trance', 'Tribal', 'Trip-Hop', 'Trop Rock', 'Vocal', 'World Music'
|
'A Cappella', 'Abstract', 'Acid', 'Acid Jazz', 'Acid Punk', 'Acoustic', 'AlternRock', 'Alternative', 'Ambient', 'Anime', 'Art Rock', 'Audio Theatre', 'Audiobook', 'Avantgarde', 'Ballad', 'Baroque', 'Bass', 'Beat', 'Bebob', 'Bhangra', 'Big Band', 'Big Beat', 'Black Metal', 'Bluegrass', 'Blues', 'Booty Bass', 'Breakbeat', 'BritPop', 'Cabaret', 'Celtic', 'Chamber Music', 'Chanson', 'Chillout', 'Chorus', 'Christian Gangsta Rap', 'Christian Rap', 'Christian Rock', 'Classic Rock', 'Classical', 'Club', 'Club-House', 'Comedy', 'Contemporary Christian', 'Country', 'Crossover', 'Cult', 'Dance', 'Dance Hall', 'Darkwave', 'Death Metal', 'Disco', 'Downtempo', 'Dream', 'Drum & Bass', 'Drum Solo', 'Dub', 'Dubstep', 'Duet', 'EBM', 'Easy Listening', 'Eclectic', 'Electro', 'Electroclash', 'Electronic', 'Emo', 'Ethnic', 'Euro-House', 'Euro-Techno', 'Eurodance', 'Experimental', 'Fast Fusion', 'Folk', 'Folk-Rock', 'Folklore', 'Freestyle', 'Funk', 'Fusion', 'G-Funk', 'Game', 'Gangsta Rap', 'Garage', 'Garage Rock', 'Global', 'Goa', 'Gospel', 'Gothic', 'Gothic Rock', 'Grunge', 'Hard Rock', 'Hardcore', 'Heavy Metal', 'Hip-Hop', 'House', 'Humour', 'IDM', 'Illbient', 'Indie', 'Indie Rock', 'Industrial', 'Industro-Goth', 'Instrumental', 'Instrumental Pop', 'Instrumental Rock', 'JPop', 'Jam Band', 'Jazz', 'Jazz+Funk', 'Jungle', 'Krautrock', 'Latin', 'Leftfield', 'Lo-Fi', 'Lounge', 'Math Rock', 'Meditative', 'Merengue', 'Metal', 'Musical', 'National Folk', 'Native American', 'Negerpunk', 'Neoclassical', 'Neue Deutsche Welle', 'New Age', 'New Romantic', 'New Wave', 'Noise', 'Nu-Breakz', 'Oldies', 'Opera', 'Other', 'Podcast', 'Polka', 'Polsk Punk', 'Pop', 'Pop / Funk', 'Pop-Folk', 'Porn Groove', 'Post-Punk', 'Post-Rock', 'Power Ballad', 'Pranks', 'Primus', 'Progressive Rock', 'Psybient', 'Psychedelic', 'Psychedelic Rock', 'Psychobilly', 'Psytrance', 'Punk', 'Punk Rock', 'R&B', 'Rap', 'Rave', 'Reggae', 'Retro', 'Revival', 'Rhythmic Soul', 'Rock', 'Rock & Roll', 'Salsa', 'Samba', 'Satire', 'Shoegaze', 'Showtunes', 'Ska', 'Slow Jam', 'Slow Rock', 'Sonata', 'Soul', 'Sound Clip', 'Soundtrack', 'Southern Rock', 'Space', 'Space Rock', 'Speech', 'Swing', 'Symphonic Rock', 'Symphony', 'Synthpop', 'Tango', 'Techno', 'Techno-Industrial', 'Terror', 'Thrash Metal', 'Top 40', 'Touhou', 'Trailer', 'Trance', 'Tribal', 'Trip-Hop', 'Trop Rock', 'Vocal', 'World Music',
|
||||||
];
|
];
|
||||||
|
|
||||||
# Taken from: https://web.archive.org/web/20220322153107/https://dev.vk.com/reference/objects/audio-genres
|
# Taken from: https://web.archive.org/web/20220322153107/https://dev.vk.com/reference/objects/audio-genres
|
||||||
const vkGenres = [
|
public const vkGenres = [
|
||||||
"Rock" => 1,
|
"Rock" => 1,
|
||||||
"Pop" => 2,
|
"Pop" => 2,
|
||||||
"Rap" => 3,
|
"Rap" => 3,
|
||||||
|
@ -51,35 +55,40 @@ class Audio extends Media
|
||||||
|
|
||||||
private function fileLength(string $filename): int
|
private function fileLength(string $filename): int
|
||||||
{
|
{
|
||||||
if(!Shell::commandAvailable("ffmpeg") || !Shell::commandAvailable("ffprobe"))
|
if (!Shell::commandAvailable("ffmpeg") || !Shell::commandAvailable("ffprobe")) {
|
||||||
throw new \Exception();
|
throw new \Exception();
|
||||||
|
}
|
||||||
|
|
||||||
$error = NULL;
|
$error = null;
|
||||||
$streams = Shell::ffprobe("-i", $filename, "-show_streams", "-select_streams a", "-loglevel error")->execute($error);
|
$streams = Shell::ffprobe("-i", $filename, "-show_streams", "-select_streams a", "-loglevel error")->execute($error);
|
||||||
if($error !== 0)
|
if ($error !== 0) {
|
||||||
throw new \DomainException("$filename is not recognized as media container");
|
throw new \DomainException("$filename is not recognized as media container");
|
||||||
else if(empty($streams) || ctype_space($streams))
|
} elseif (empty($streams) || ctype_space($streams)) {
|
||||||
throw new \DomainException("$filename does not contain any audio streams");
|
throw new \DomainException("$filename does not contain any audio streams");
|
||||||
|
}
|
||||||
|
|
||||||
$vstreams = Shell::ffprobe("-i", $filename, "-show_streams", "-select_streams v", "-loglevel error")->execute($error);
|
$vstreams = Shell::ffprobe("-i", $filename, "-show_streams", "-select_streams v", "-loglevel error")->execute($error);
|
||||||
|
|
||||||
# check if audio has cover (attached_pic)
|
# check if audio has cover (attached_pic)
|
||||||
preg_match("%attached_pic=([0-1])%", $vstreams, $hasCover);
|
preg_match("%attached_pic=([0-1])%", $vstreams, $hasCover);
|
||||||
if(!empty($vstreams) && !ctype_space($vstreams) && ((int)($hasCover[1]) !== 1))
|
if (!empty($vstreams) && !ctype_space($vstreams) && ((int) ($hasCover[1]) !== 1)) {
|
||||||
throw new \DomainException("$filename is a video");
|
throw new \DomainException("$filename is a video");
|
||||||
|
}
|
||||||
|
|
||||||
$durations = [];
|
$durations = [];
|
||||||
preg_match_all('%duration=([0-9\.]++)%', $streams, $durations);
|
preg_match_all('%duration=([0-9\.]++)%', $streams, $durations);
|
||||||
if(sizeof($durations[1]) === 0)
|
if (sizeof($durations[1]) === 0) {
|
||||||
throw new \DomainException("$filename does not contain any meaningful audio streams");
|
throw new \DomainException("$filename does not contain any meaningful audio streams");
|
||||||
|
}
|
||||||
|
|
||||||
$length = 0;
|
$length = 0;
|
||||||
foreach($durations[1] as $duration) {
|
foreach ($durations[1] as $duration) {
|
||||||
$duration = floatval($duration);
|
$duration = floatval($duration);
|
||||||
if($duration < 1.0 || $duration > 65536.0)
|
if ($duration < 1.0 || $duration > 65536.0) {
|
||||||
throw new \DomainException("$filename does not contain any meaningful audio streams");
|
throw new \DomainException("$filename does not contain any meaningful audio streams");
|
||||||
else
|
} else {
|
||||||
$length = max($length, $duration);
|
$length = max($length, $duration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int) round($length, 0, PHP_ROUND_HALF_EVEN);
|
return (int) round($length, 0, PHP_ROUND_HALF_EVEN);
|
||||||
|
@ -116,7 +125,7 @@ class Audio extends Media
|
||||||
$ss,
|
$ss,
|
||||||
];
|
];
|
||||||
|
|
||||||
if(Shell::isPowershell()) {
|
if (Shell::isPowershell()) {
|
||||||
Shell::powershell("-executionpolicy bypass", "-File", __DIR__ . "/../shell/processAudio.ps1", ...$args)
|
Shell::powershell("-executionpolicy bypass", "-File", __DIR__ . "/../shell/processAudio.ps1", ...$args)
|
||||||
->start();
|
->start();
|
||||||
} else {
|
} else {
|
||||||
|
@ -126,58 +135,60 @@ class Audio extends Media
|
||||||
|
|
||||||
# Wait until processAudio will consume the file
|
# Wait until processAudio will consume the file
|
||||||
$start = time();
|
$start = time();
|
||||||
while(file_exists($filename))
|
while (file_exists($filename)) {
|
||||||
if(time() - $start > 5)
|
if (time() - $start > 5) {
|
||||||
throw new \RuntimeException("Timed out waiting FFMPEG");
|
throw new \RuntimeException("Timed out waiting FFMPEG");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} catch(UnknownCommandException $ucex) {
|
} catch (UnknownCommandException $ucex) {
|
||||||
exit(OPENVK_ROOT_CONF["openvk"]["debug"] ? "bash/pwsh is not installed" : VIDEOS_FRIENDLY_ERROR);
|
exit(OPENVK_ROOT_CONF["openvk"]["debug"] ? "bash/pwsh is not installed" : VIDEOS_FRIENDLY_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTitle(): string
|
public function getTitle(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->name;
|
return $this->getRecord()->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPerformer(): string
|
public function getPerformer(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->performer;
|
return $this->getRecord()->performer;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPerformers(): array
|
public function getPerformers(): array
|
||||||
{
|
{
|
||||||
return explode(", ", $this->getRecord()->performer);
|
return explode(", ", $this->getRecord()->performer);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getName(): string
|
public function getName(): string
|
||||||
{
|
{
|
||||||
return $this->getPerformer() . " — " . $this->getTitle();
|
return $this->getPerformer() . " — " . $this->getTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDownloadName(): string
|
public function getDownloadName(): string
|
||||||
{
|
{
|
||||||
return preg_replace('/[\\/:*?"<>|]/', '_', str_replace(' ', '_', $this->getName()));
|
return preg_replace('/[\\/:*?"<>|]/', '_', str_replace(' ', '_', $this->getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGenre(): ?string
|
public function getGenre(): ?string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->genre;
|
return $this->getRecord()->genre;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLyrics(): ?string
|
public function getLyrics(): ?string
|
||||||
{
|
{
|
||||||
return !is_null($this->getRecord()->lyrics) ? htmlspecialchars($this->getRecord()->lyrics, ENT_DISALLOWED | ENT_XHTML) : NULL;
|
return !is_null($this->getRecord()->lyrics) ? htmlspecialchars($this->getRecord()->lyrics, ENT_DISALLOWED | ENT_XHTML) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLength(): int
|
public function getLength(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->length;
|
return $this->getRecord()->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFormattedLength(): string
|
public function getFormattedLength(): string
|
||||||
{
|
{
|
||||||
$len = $this->getLength();
|
$len = $this->getLength();
|
||||||
$mins = floor($len / 60);
|
$mins = floor($len / 60);
|
||||||
|
@ -190,78 +201,83 @@ class Audio extends Media
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSegmentSize(): float
|
public function getSegmentSize(): float
|
||||||
{
|
{
|
||||||
return $this->getRecord()->segment_size;
|
return $this->getRecord()->segment_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getListens(): int
|
public function getListens(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->listens;
|
return $this->getRecord()->listens;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOriginalURL(bool $force = false): string
|
public function getOriginalURL(bool $force = false): string
|
||||||
{
|
{
|
||||||
$disallowed = !OPENVK_ROOT_CONF["openvk"]["preferences"]["music"]["exposeOriginalURLs"] && !$force;
|
$disallowed = !OPENVK_ROOT_CONF["openvk"]["preferences"]["music"]["exposeOriginalURLs"] && !$force;
|
||||||
if(!$this->isAvailable() || $disallowed)
|
if (!$this->isAvailable() || $disallowed) {
|
||||||
return ovk_scheme(true)
|
return ovk_scheme(true)
|
||||||
. $_SERVER["HTTP_HOST"] . ":"
|
. $_SERVER["HTTP_HOST"] . ":"
|
||||||
. $_SERVER["HTTP_PORT"]
|
. $_SERVER["HTTP_PORT"]
|
||||||
. "/assets/packages/static/openvk/audio/nomusic.mp3";
|
. "/assets/packages/static/openvk/audio/nomusic.mp3";
|
||||||
|
}
|
||||||
|
|
||||||
$key = bin2hex($this->getRecord()->token);
|
$key = bin2hex($this->getRecord()->token);
|
||||||
|
|
||||||
return str_replace(".mpd", "_fragments", $this->getURL()) . "/original_$key.mp3";
|
return str_replace(".mpd", "_fragments", $this->getURL()) . "/original_$key.mp3";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getURL(?bool $force = false): string
|
public function getURL(?bool $force = false): string
|
||||||
{
|
{
|
||||||
if ($this->isWithdrawn()) return "";
|
if ($this->isWithdrawn()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
return parent::getURL();
|
return parent::getURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getKeys(): array
|
public function getKeys(): array
|
||||||
{
|
{
|
||||||
$keys[bin2hex($this->getRecord()->kid)] = bin2hex($this->getRecord()->key);
|
$keys[bin2hex($this->getRecord()->kid)] = bin2hex($this->getRecord()->key);
|
||||||
|
|
||||||
return $keys;
|
return $keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAnonymous(): bool
|
public function isAnonymous(): bool
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isExplicit(): bool
|
public function isExplicit(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->explicit;
|
return (bool) $this->getRecord()->explicit;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isWithdrawn(): bool
|
public function isWithdrawn(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->withdrawn;
|
return (bool) $this->getRecord()->withdrawn;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isUnlisted(): bool
|
public function isUnlisted(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->unlisted;
|
return (bool) $this->getRecord()->unlisted;
|
||||||
}
|
}
|
||||||
|
|
||||||
# NOTICE may flush model to DB if it was just processed
|
# NOTICE may flush model to DB if it was just processed
|
||||||
function isAvailable(): bool
|
public function isAvailable(): bool
|
||||||
{
|
{
|
||||||
if($this->getRecord()->processed)
|
if ($this->getRecord()->processed) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
# throttle requests to isAvailable to prevent DoS attack if filesystem is actually an S3 storage
|
# throttle requests to isAvailable to prevent DoS attack if filesystem is actually an S3 storage
|
||||||
if(time() - $this->getRecord()->checked < 5)
|
if (time() - $this->getRecord()->checked < 5) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$fragments = str_replace(".mpd", "_fragments", $this->getFileName());
|
$fragments = str_replace(".mpd", "_fragments", $this->getFileName());
|
||||||
$original = "original_" . bin2hex($this->getRecord()->token) . ".mp3";
|
$original = "original_" . bin2hex($this->getRecord()->token) . ".mp3";
|
||||||
if(file_exists("$fragments/$original")) {
|
if (file_exists("$fragments/$original")) {
|
||||||
# Original gets uploaded after fragments
|
# Original gets uploaded after fragments
|
||||||
$this->stateChanges("processed", 0x01);
|
$this->stateChanges("processed", 0x01);
|
||||||
|
|
||||||
|
@ -275,7 +291,7 @@ class Audio extends Media
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isInLibraryOf($entity): bool
|
public function isInLibraryOf($entity): bool
|
||||||
{
|
{
|
||||||
return sizeof(DatabaseConnection::i()->getContext()->table("audio_relations")->where([
|
return sizeof(DatabaseConnection::i()->getContext()->table("audio_relations")->where([
|
||||||
"entity" => $entity->getId() * ($entity instanceof Club ? -1 : 1),
|
"entity" => $entity->getId() * ($entity instanceof Club ? -1 : 1),
|
||||||
|
@ -283,15 +299,17 @@ class Audio extends Media
|
||||||
])) != 0;
|
])) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function add($entity): bool
|
public function add($entity): bool
|
||||||
{
|
{
|
||||||
if($this->isInLibraryOf($entity))
|
if ($this->isInLibraryOf($entity)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$entityId = $entity->getId() * ($entity instanceof Club ? -1 : 1);
|
$entityId = $entity->getId() * ($entity instanceof Club ? -1 : 1);
|
||||||
$audioRels = DatabaseConnection::i()->getContext()->table("audio_relations");
|
$audioRels = DatabaseConnection::i()->getContext()->table("audio_relations");
|
||||||
if(sizeof($audioRels->where("entity", $entityId)) > 65536)
|
if (sizeof($audioRels->where("entity", $entityId)) > 65536) {
|
||||||
throw new \OverflowException("Can't have more than 65536 audios in a playlist");
|
throw new \OverflowException("Can't have more than 65536 audios in a playlist");
|
||||||
|
}
|
||||||
|
|
||||||
$audioRels->insert([
|
$audioRels->insert([
|
||||||
"entity" => $entityId,
|
"entity" => $entityId,
|
||||||
|
@ -301,10 +319,11 @@ class Audio extends Media
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function remove($entity): bool
|
public function remove($entity): bool
|
||||||
{
|
{
|
||||||
if(!$this->isInLibraryOf($entity))
|
if (!$this->isInLibraryOf($entity)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
DatabaseConnection::i()->getContext()->table("audio_relations")->where([
|
DatabaseConnection::i()->getContext()->table("audio_relations")->where([
|
||||||
"entity" => $entity->getId() * ($entity instanceof Club ? -1 : 1),
|
"entity" => $entity->getId() * ($entity instanceof Club ? -1 : 1),
|
||||||
|
@ -314,27 +333,27 @@ class Audio extends Media
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function listen($entity, Playlist $playlist = NULL): bool
|
public function listen($entity, Playlist $playlist = null): bool
|
||||||
{
|
{
|
||||||
$listensTable = DatabaseConnection::i()->getContext()->table("audio_listens");
|
$listensTable = DatabaseConnection::i()->getContext()->table("audio_listens");
|
||||||
$lastListen = $listensTable->where([
|
$lastListen = $listensTable->where([
|
||||||
"entity" => $entity->getRealId(),
|
"entity" => $entity->getRealId(),
|
||||||
"audio" => $this->getId(),
|
"audio" => $this->getId(),
|
||||||
])->order("index DESC")->fetch();
|
])->order("index DESC")->fetch();
|
||||||
|
|
||||||
if(!$lastListen || (time() - $lastListen->time >= $this->getLength())) {
|
if (!$lastListen || (time() - $lastListen->time >= $this->getLength())) {
|
||||||
$listensTable->insert([
|
$listensTable->insert([
|
||||||
"entity" => $entity->getRealId(),
|
"entity" => $entity->getRealId(),
|
||||||
"audio" => $this->getId(),
|
"audio" => $this->getId(),
|
||||||
"time" => time(),
|
"time" => time(),
|
||||||
"playlist" => $playlist ? $playlist->getId() : NULL,
|
"playlist" => $playlist ? $playlist->getId() : null,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if($entity instanceof User) {
|
if ($entity instanceof User) {
|
||||||
$this->stateChanges("listens", ($this->getListens() + 1));
|
$this->stateChanges("listens", ($this->getListens() + 1));
|
||||||
$this->save();
|
$this->save();
|
||||||
|
|
||||||
if($playlist) {
|
if ($playlist) {
|
||||||
$playlist->incrementListens();
|
$playlist->incrementListens();
|
||||||
$playlist->save();
|
$playlist->save();
|
||||||
}
|
}
|
||||||
|
@ -380,7 +399,7 @@ class Audio extends Media
|
||||||
* @param ?User $user user, relative to whom "added", "editable" will be set
|
* @param ?User $user user, relative to whom "added", "editable" will be set
|
||||||
* @param bool $forceURLExposure force set "url" regardless of config
|
* @param bool $forceURLExposure force set "url" regardless of config
|
||||||
*/
|
*/
|
||||||
function toVkApiStruct(?User $user = NULL, bool $forceURLExposure = false): object
|
public function toVkApiStruct(?User $user = null, bool $forceURLExposure = false): object
|
||||||
{
|
{
|
||||||
$obj = (object) [];
|
$obj = (object) [];
|
||||||
$obj->unique_id = base64_encode((string) $this->getId());
|
$obj->unique_id = base64_encode((string) $this->getId());
|
||||||
|
@ -388,19 +407,21 @@ class Audio extends Media
|
||||||
$obj->artist = $this->getPerformer();
|
$obj->artist = $this->getPerformer();
|
||||||
$obj->title = $this->getTitle();
|
$obj->title = $this->getTitle();
|
||||||
$obj->duration = $this->getLength();
|
$obj->duration = $this->getLength();
|
||||||
$obj->album_id = $obj->album = NULL; # i forgor to implement
|
$obj->album_id = $obj->album = null; # i forgor to implement
|
||||||
$obj->url = false;
|
$obj->url = false;
|
||||||
$obj->manifest = false;
|
$obj->manifest = false;
|
||||||
$obj->keys = false;
|
$obj->keys = false;
|
||||||
$obj->genre_id = $obj->genre = self::vkGenres[$this->getGenre() ?? ""] ?? 18; # return Other if no match
|
$obj->genre_id = $obj->genre = self::vkGenres[$this->getGenre() ?? ""] ?? 18; # return Other if no match
|
||||||
$obj->genre_str = $this->getGenre();
|
$obj->genre_str = $this->getGenre();
|
||||||
$obj->owner_id = $this->getOwner()->getId();
|
$obj->owner_id = $this->getOwner()->getId();
|
||||||
if($this->getOwner() instanceof Club)
|
if ($this->getOwner() instanceof Club) {
|
||||||
$obj->owner_id *= -1;
|
$obj->owner_id *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
$obj->lyrics = NULL;
|
$obj->lyrics = null;
|
||||||
if(!is_null($this->getLyrics()))
|
if (!is_null($this->getLyrics())) {
|
||||||
$obj->lyrics = $this->getId();
|
$obj->lyrics = $this->getId();
|
||||||
|
}
|
||||||
|
|
||||||
$obj->added = $user && $this->isInLibraryOf($user);
|
$obj->added = $user && $this->isInLibraryOf($user);
|
||||||
$obj->editable = $user && $this->canBeModifiedBy($user);
|
$obj->editable = $user && $this->canBeModifiedBy($user);
|
||||||
|
@ -408,7 +429,7 @@ class Audio extends Media
|
||||||
$obj->explicit = $this->isExplicit();
|
$obj->explicit = $this->isExplicit();
|
||||||
$obj->withdrawn = $this->isWithdrawn();
|
$obj->withdrawn = $this->isWithdrawn();
|
||||||
$obj->ready = $this->isAvailable() && !$obj->withdrawn;
|
$obj->ready = $this->isAvailable() && !$obj->withdrawn;
|
||||||
if($obj->ready) {
|
if ($obj->ready) {
|
||||||
$obj->url = $this->getOriginalURL($forceURLExposure);
|
$obj->url = $this->getOriginalURL($forceURLExposure);
|
||||||
$obj->manifest = $this->getURL();
|
$obj->manifest = $this->getURL();
|
||||||
$obj->keys = $this->getKeys();
|
$obj->keys = $this->getKeys();
|
||||||
|
@ -417,54 +438,62 @@ class Audio extends Media
|
||||||
return $obj;
|
return $obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setOwner(int $oid): void
|
public function setOwner(int $oid): void
|
||||||
{
|
{
|
||||||
# WARNING: API implementation won't be able to handle groups like that, don't remove
|
# WARNING: API implementation won't be able to handle groups like that, don't remove
|
||||||
if($oid <= 0)
|
if ($oid <= 0) {
|
||||||
throw new \OutOfRangeException("Only users can be owners of audio!");
|
throw new \OutOfRangeException("Only users can be owners of audio!");
|
||||||
|
}
|
||||||
|
|
||||||
$this->stateChanges("owner", $oid);
|
$this->stateChanges("owner", $oid);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setGenre(string $genre): void
|
public function setGenre(string $genre): void
|
||||||
{
|
{
|
||||||
if(!in_array($genre, Audio::genres)) {
|
if (!in_array($genre, Audio::genres)) {
|
||||||
$this->stateChanges("genre", NULL);
|
$this->stateChanges("genre", null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->stateChanges("genre", $genre);
|
$this->stateChanges("genre", $genre);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setCopyrightStatus(bool $withdrawn = true): void {
|
public function setCopyrightStatus(bool $withdrawn = true): void
|
||||||
|
{
|
||||||
$this->stateChanges("withdrawn", $withdrawn);
|
$this->stateChanges("withdrawn", $withdrawn);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSearchability(bool $searchable = true): void {
|
public function setSearchability(bool $searchable = true): void
|
||||||
|
{
|
||||||
$this->stateChanges("unlisted", !$searchable);
|
$this->stateChanges("unlisted", !$searchable);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setToken(string $tok): void {
|
public function setToken(string $tok): void
|
||||||
|
{
|
||||||
throw new \LogicException("Changing keys is not supported.");
|
throw new \LogicException("Changing keys is not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
function setKid(string $kid): void {
|
public function setKid(string $kid): void
|
||||||
|
{
|
||||||
throw new \LogicException("Changing keys is not supported.");
|
throw new \LogicException("Changing keys is not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
function setKey(string $key): void {
|
public function setKey(string $key): void
|
||||||
|
{
|
||||||
throw new \LogicException("Changing keys is not supported.");
|
throw new \LogicException("Changing keys is not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLength(int $len): void {
|
public function setLength(int $len): void
|
||||||
|
{
|
||||||
throw new \LogicException("Changing length is not supported.");
|
throw new \LogicException("Changing length is not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSegment_Size(int $len): void {
|
public function setSegment_Size(int $len): void
|
||||||
|
{
|
||||||
throw new \LogicException("Changing length is not supported.");
|
throw new \LogicException("Changing length is not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete(bool $softly = true): void
|
public function delete(bool $softly = true): void
|
||||||
{
|
{
|
||||||
$ctx = DatabaseConnection::i()->getContext();
|
$ctx = DatabaseConnection::i()->getContext();
|
||||||
$ctx->table("audio_relations")->where("audio", $this->getId())
|
$ctx->table("audio_relations")->where("audio", $this->getId())
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
use openvk\Web\Models\Repositories\{Users};
|
use openvk\Web\Models\Repositories\{Users};
|
||||||
|
@ -9,58 +13,58 @@ class Ban extends RowModel
|
||||||
{
|
{
|
||||||
protected $tableName = "bans";
|
protected $tableName = "bans";
|
||||||
|
|
||||||
function getId(): int
|
public function getId(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->id;
|
return $this->getRecord()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getReason(): ?string
|
public function getReason(): ?string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->reason;
|
return $this->getRecord()->reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUser(): ?User
|
public function getUser(): ?User
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getRecord()->user);
|
return (new Users())->get($this->getRecord()->user);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInitiator(): ?User
|
public function getInitiator(): ?User
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getRecord()->initiator);
|
return (new Users())->get($this->getRecord()->initiator);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStartTime(): int
|
public function getStartTime(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->iat;
|
return $this->getRecord()->iat;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEndTime(): int
|
public function getEndTime(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->exp;
|
return $this->getRecord()->exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTime(): int
|
public function getTime(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->time;
|
return $this->getRecord()->time;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPermanent(): bool
|
public function isPermanent(): bool
|
||||||
{
|
{
|
||||||
return $this->getEndTime() === 0;
|
return $this->getEndTime() === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isRemovedManually(): bool
|
public function isRemovedManually(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->removed_manually;
|
return (bool) $this->getRecord()->removed_manually;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isOver(): bool
|
public function isOver(): bool
|
||||||
{
|
{
|
||||||
return $this->isRemovedManually();
|
return $this->isRemovedManually();
|
||||||
}
|
}
|
||||||
|
|
||||||
function whoRemoved(): ?User
|
public function whoRemoved(): ?User
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getRecord()->removed_by);
|
return (new Users())->get($this->getRecord()->removed_by);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Models\Entities\{User};
|
use openvk\Web\Models\Entities\{User};
|
||||||
use openvk\Web\Models\Repositories\{Users};
|
use openvk\Web\Models\Repositories\{Users};
|
||||||
|
@ -10,39 +14,39 @@ class BannedLink extends RowModel
|
||||||
protected $tableName = "links_banned";
|
protected $tableName = "links_banned";
|
||||||
private $overrideContentColumn = "reason";
|
private $overrideContentColumn = "reason";
|
||||||
|
|
||||||
function getId(): int
|
public function getId(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->id;
|
return $this->getRecord()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDomain(): string
|
public function getDomain(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->domain;
|
return $this->getRecord()->domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getReason(): string
|
public function getReason(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->reason ?? tr("url_is_banned_default_reason");
|
return $this->getRecord()->reason ?? tr("url_is_banned_default_reason");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInitiator(): ?User
|
public function getInitiator(): ?User
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getRecord()->initiator);
|
return (new Users())->get($this->getRecord()->initiator);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComment(): string
|
public function getComment(): string
|
||||||
{
|
{
|
||||||
return OPENVK_ROOT_CONF["openvk"]["preferences"]["susLinks"]["showReason"]
|
return OPENVK_ROOT_CONF["openvk"]["preferences"]["susLinks"]["showReason"]
|
||||||
? tr("url_is_banned_comment_r", OPENVK_ROOT_CONF["openvk"]["appearance"]["name"], $this->getReason())
|
? tr("url_is_banned_comment_r", OPENVK_ROOT_CONF["openvk"]["appearance"]["name"], $this->getReason())
|
||||||
: tr("url_is_banned_comment", OPENVK_ROOT_CONF["openvk"]["appearance"]["name"]);
|
: tr("url_is_banned_comment", OPENVK_ROOT_CONF["openvk"]["appearance"]["name"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRegexpRule(): string
|
public function getRegexpRule(): string
|
||||||
{
|
{
|
||||||
return addslashes("/" . $this->getDomain() . $this->getRawRegexp() . "/");
|
return addslashes("/" . $this->getDomain() . $this->getRawRegexp() . "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRawRegexp(): string
|
public function getRawRegexp(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->regexp_rule;
|
return $this->getRecord()->regexp_rule;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Models\Entities\{User, Manager};
|
use openvk\Web\Models\Entities\{User, Manager};
|
||||||
|
@ -10,234 +14,250 @@ use Chandler\Security\User as ChandlerUser;
|
||||||
|
|
||||||
class Club extends RowModel
|
class Club extends RowModel
|
||||||
{
|
{
|
||||||
|
use Traits\TBackDrops;
|
||||||
|
use Traits\TSubscribable;
|
||||||
|
use Traits\TAudioStatuses;
|
||||||
|
use Traits\TIgnorable;
|
||||||
protected $tableName = "groups";
|
protected $tableName = "groups";
|
||||||
|
|
||||||
const TYPE_GROUP = 1;
|
|
||||||
const TYPE_PUBLIC = 1;
|
|
||||||
const TYPE_EVENT = 2;
|
|
||||||
|
|
||||||
const OPEN = 0;
|
|
||||||
const CLOSED = 1;
|
|
||||||
const PRIVATE = 2;
|
|
||||||
|
|
||||||
const NOT_RELATED = 0;
|
|
||||||
const SUBSCRIBED = 1;
|
|
||||||
const REQUEST_SENT = 2;
|
|
||||||
|
|
||||||
const WALL_CLOSED = 0;
|
public const TYPE_GROUP = 1;
|
||||||
const WALL_OPEN = 1;
|
public const TYPE_PUBLIC = 1;
|
||||||
const WALL_LIMITED = 2;
|
public const TYPE_EVENT = 2;
|
||||||
|
|
||||||
function getId(): int
|
public const OPEN = 0;
|
||||||
|
public const CLOSED = 1;
|
||||||
|
public const PRIVATE = 2;
|
||||||
|
|
||||||
|
public const NOT_RELATED = 0;
|
||||||
|
public const SUBSCRIBED = 1;
|
||||||
|
public const REQUEST_SENT = 2;
|
||||||
|
|
||||||
|
public const WALL_CLOSED = 0;
|
||||||
|
public const WALL_OPEN = 1;
|
||||||
|
public const WALL_LIMITED = 2;
|
||||||
|
|
||||||
|
public function getId(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->id;
|
return $this->getRecord()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAvatarPhoto(): ?Photo
|
public function getAvatarPhoto(): ?Photo
|
||||||
{
|
{
|
||||||
$avAlbum = (new Albums)->getClubAvatarAlbum($this);
|
$avAlbum = (new Albums())->getClubAvatarAlbum($this);
|
||||||
$avCount = $avAlbum->getPhotosCount();
|
$avCount = $avAlbum->getPhotosCount();
|
||||||
$avPhotos = $avAlbum->getPhotos($avCount, 1);
|
$avPhotos = $avAlbum->getPhotos($avCount, 1);
|
||||||
|
|
||||||
return iterator_to_array($avPhotos)[0] ?? NULL;
|
return iterator_to_array($avPhotos)[0] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAvatarUrl(string $size = "miniscule", $avPhoto = NULL): string
|
public function getAvatarUrl(string $size = "miniscule", $avPhoto = null): string
|
||||||
{
|
{
|
||||||
$serverUrl = ovk_scheme(true) . $_SERVER["HTTP_HOST"];
|
$serverUrl = ovk_scheme(true) . $_SERVER["HTTP_HOST"];
|
||||||
if(!$avPhoto)
|
if (!$avPhoto) {
|
||||||
$avPhoto = $this->getAvatarPhoto();
|
$avPhoto = $this->getAvatarPhoto();
|
||||||
|
}
|
||||||
|
|
||||||
return is_null($avPhoto) ? "$serverUrl/assets/packages/static/openvk/img/camera_200.png" : $avPhoto->getURLBySizeId($size);
|
return is_null($avPhoto) ? "$serverUrl/assets/packages/static/openvk/img/camera_200.png" : $avPhoto->getURLBySizeId($size);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getWallType(): int
|
public function getWallType(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->wall;
|
return $this->getRecord()->wall;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAvatarLink(): string
|
public function getAvatarLink(): string
|
||||||
{
|
{
|
||||||
$avPhoto = $this->getAvatarPhoto();
|
$avPhoto = $this->getAvatarPhoto();
|
||||||
if(!$avPhoto) return "javascript:void(0)";
|
if (!$avPhoto) {
|
||||||
|
return "javascript:void(0)";
|
||||||
|
}
|
||||||
|
|
||||||
$pid = $avPhoto->getPrettyId();
|
$pid = $avPhoto->getPrettyId();
|
||||||
$aid = (new Albums)->getClubAvatarAlbum($this)->getId();
|
$aid = (new Albums())->getClubAvatarAlbum($this)->getId();
|
||||||
|
|
||||||
return "/photo$pid?from=album$aid";
|
return "/photo$pid?from=album$aid";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getURL(): string
|
public function getURL(): string
|
||||||
{
|
{
|
||||||
if(!is_null($this->getShortCode()))
|
if (!is_null($this->getShortCode())) {
|
||||||
return "/" . $this->getShortCode();
|
return "/" . $this->getShortCode();
|
||||||
else
|
} else {
|
||||||
return "/club" . $this->getId();
|
return "/club" . $this->getId();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getName(): string
|
public function getName(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->name;
|
return $this->getRecord()->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCanonicalName(): string
|
public function getCanonicalName(): string
|
||||||
{
|
{
|
||||||
return $this->getName();
|
return $this->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOwner(): ?User
|
public function getOwner(): ?User
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getRecord()->owner);
|
return (new Users())->get($this->getRecord()->owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOwnerComment(): string
|
public function getOwnerComment(): string
|
||||||
{
|
{
|
||||||
return is_null($this->getRecord()->owner_comment) ? "" : $this->getRecord()->owner_comment;
|
return is_null($this->getRecord()->owner_comment) ? "" : $this->getRecord()->owner_comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isOwnerHidden(): bool
|
public function isOwnerHidden(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->owner_hidden;
|
return (bool) $this->getRecord()->owner_hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isOwnerClubPinned(): bool
|
public function isOwnerClubPinned(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->owner_club_pinned;
|
return (bool) $this->getRecord()->owner_club_pinned;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDescription(): ?string
|
public function getDescription(): ?string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->about;
|
return $this->getRecord()->about;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDescriptionHtml(): ?string
|
public function getDescriptionHtml(): ?string
|
||||||
{
|
{
|
||||||
if(!is_null($this->getDescription()))
|
if (!is_null($this->getDescription())) {
|
||||||
return nl2br(htmlspecialchars($this->getDescription(), ENT_DISALLOWED | ENT_XHTML));
|
return nl2br(htmlspecialchars($this->getDescription(), ENT_DISALLOWED | ENT_XHTML));
|
||||||
else
|
} else {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getShortCode(): ?string
|
public function getShortCode(): ?string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->shortcode;
|
return $this->getRecord()->shortcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBanReason(): ?string
|
public function getBanReason(): ?string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->block_reason;
|
return $this->getRecord()->block_reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOpennesStatus(): int
|
public function getOpennesStatus(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->closed;
|
return $this->getRecord()->closed;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAdministratorsListDisplay(): int
|
public function getAdministratorsListDisplay(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->administrators_list_display;
|
return $this->getRecord()->administrators_list_display;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isEveryoneCanCreateTopics(): bool
|
public function isEveryoneCanCreateTopics(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->everyone_can_create_topics;
|
return (bool) $this->getRecord()->everyone_can_create_topics;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDisplayTopicsAboveWallEnabled(): bool
|
public function isDisplayTopicsAboveWallEnabled(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->display_topics_above_wall;
|
return (bool) $this->getRecord()->display_topics_above_wall;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isHideFromGlobalFeedEnabled(): bool
|
public function isHideFromGlobalFeedEnabled(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->hide_from_global_feed;
|
return (bool) $this->getRecord()->hide_from_global_feed;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isHidingFromGlobalFeedEnforced(): bool
|
public function isHidingFromGlobalFeedEnforced(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->enforce_hiding_from_global_feed;
|
return (bool) $this->getRecord()->enforce_hiding_from_global_feed;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getType(): int
|
public function getType(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->type;
|
return $this->getRecord()->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isVerified(): bool
|
public function isVerified(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->verified;
|
return (bool) $this->getRecord()->verified;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isBanned(): bool
|
public function isBanned(): bool
|
||||||
{
|
{
|
||||||
return !is_null($this->getBanReason());
|
return !is_null($this->getBanReason());
|
||||||
}
|
}
|
||||||
|
|
||||||
function canPost(): bool
|
public function canPost(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->wall;
|
return (bool) $this->getRecord()->wall;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function setShortCode(?string $code = NULL): ?bool
|
public function setShortCode(?string $code = null): ?bool
|
||||||
{
|
{
|
||||||
if(!is_null($code)) {
|
if (!is_null($code)) {
|
||||||
if(!preg_match("%^[a-z][a-z0-9\\.\\_]{0,30}[a-z0-9]$%", $code))
|
if (!preg_match("%^[a-z][a-z0-9\\.\\_]{0,30}[a-z0-9]$%", $code)) {
|
||||||
return false;
|
return false;
|
||||||
if(in_array($code, OPENVK_ROOT_CONF["openvk"]["preferences"]["shortcodes"]["forbiddenNames"]))
|
}
|
||||||
|
if (in_array($code, OPENVK_ROOT_CONF["openvk"]["preferences"]["shortcodes"]["forbiddenNames"])) {
|
||||||
return false;
|
return false;
|
||||||
if(\Chandler\MVC\Routing\Router::i()->getMatchingRoute("/$code")[0]->presenter !== "UnknownTextRouteStrategy")
|
}
|
||||||
|
if (\Chandler\MVC\Routing\Router::i()->getMatchingRoute("/$code")[0]->presenter !== "UnknownTextRouteStrategy") {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$pUser = DB::i()->getContext()->table("profiles")->where("shortcode", $code)->fetch();
|
$pUser = DB::i()->getContext()->table("profiles")->where("shortcode", $code)->fetch();
|
||||||
if(!is_null($pUser))
|
if (!is_null($pUser)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->stateChanges("shortcode", $code);
|
$this->stateChanges("shortcode", $code);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setWall(int $type)
|
public function setWall(int $type)
|
||||||
{
|
{
|
||||||
if($type > 2 || $type < 0)
|
if ($type > 2 || $type < 0) {
|
||||||
throw new \LogicException("Invalid wall");
|
throw new \LogicException("Invalid wall");
|
||||||
|
}
|
||||||
|
|
||||||
$this->stateChanges("wall", $type);
|
$this->stateChanges("wall", $type);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSubscriptionAccepted(User $user): bool
|
public function isSubscriptionAccepted(User $user): bool
|
||||||
{
|
{
|
||||||
return !is_null($this->getRecord()->related("subscriptions.follower")->where([
|
return !is_null($this->getRecord()->related("subscriptions.follower")->where([
|
||||||
"follower" => $this->getId(),
|
"follower" => $this->getId(),
|
||||||
"target" => $user->getId(),
|
"target" => $user->getId(),
|
||||||
])->fetch());;
|
])->fetch());
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPostViewStats(bool $unique = false): ?array
|
public function getPostViewStats(bool $unique = false): ?array
|
||||||
{
|
{
|
||||||
$edb = eventdb();
|
$edb = eventdb();
|
||||||
if(!$edb)
|
if (!$edb) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
$subs = [];
|
$subs = [];
|
||||||
$viral = [];
|
$viral = [];
|
||||||
$total = [];
|
$total = [];
|
||||||
for($i = 1; $i < 8; $i++) {
|
for ($i = 1; $i < 8; $i++) {
|
||||||
$begin = strtotime("-" . $i . "day midnight");
|
$begin = strtotime("-" . $i . "day midnight");
|
||||||
$end = $i === 1 ? time() + 10 : strtotime("-" . ($i - 1) . "day midnight");
|
$end = $i === 1 ? time() + 10 : strtotime("-" . ($i - 1) . "day midnight");
|
||||||
|
|
||||||
$query = "SELECT COUNT(" . ($unique ? "DISTINCT profile" : "*") . ") AS cnt FROM postViews";
|
$query = "SELECT COUNT(" . ($unique ? "DISTINCT profile" : "*") . ") AS cnt FROM postViews";
|
||||||
$query .= " WHERE `group`=1 AND owner=" . $this->getId();
|
$query .= " WHERE `group`=1 AND owner=" . $this->getId();
|
||||||
$query .= " AND timestamp > $begin AND timestamp < $end";
|
$query .= " AND timestamp > $begin AND timestamp < $end";
|
||||||
|
|
||||||
$sub = $edb->getConnection()->query("$query AND NOT subscribed=0")->fetch()->cnt;
|
$sub = $edb->getConnection()->query("$query AND NOT subscribed=0")->fetch()->cnt;
|
||||||
$vir = $edb->getConnection()->query("$query AND subscribed=0")->fetch()->cnt;
|
$vir = $edb->getConnection()->query("$query AND subscribed=0")->fetch()->cnt;
|
||||||
$subs[] = $sub;
|
$subs[] = $sub;
|
||||||
$viral[] = $vir;
|
$viral[] = $vir;
|
||||||
$total[] = $sub + $vir;
|
$total[] = $sub + $vir;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
"total" => [
|
"total" => [
|
||||||
"x" => array_reverse(range(1, 7)),
|
"x" => array_reverse(range(1, 7)),
|
||||||
|
@ -273,96 +293,105 @@ class Club extends RowModel
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSubscriptionStatus(User $user): bool
|
public function getSubscriptionStatus(User $user): bool
|
||||||
{
|
{
|
||||||
$subbed = !is_null($this->getRecord()->related("subscriptions.target")->where([
|
$subbed = !is_null($this->getRecord()->related("subscriptions.target")->where([
|
||||||
"target" => $this->getId(),
|
"target" => $this->getId(),
|
||||||
"model" => static::class,
|
"model" => static::class,
|
||||||
"follower" => $user->getId(),
|
"follower" => $user->getId(),
|
||||||
])->fetch());
|
])->fetch());
|
||||||
|
|
||||||
return $subbed && ($this->getOpennesStatus() === static::CLOSED ? $this->isSubscriptionAccepted($user) : true);
|
return $subbed && ($this->getOpennesStatus() === static::CLOSED ? $this->isSubscriptionAccepted($user) : true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFollowersQuery(string $sort = "follower ASC"): GroupedSelection
|
public function getFollowersQuery(string $sort = "follower ASC"): GroupedSelection
|
||||||
{
|
{
|
||||||
$query = $this->getRecord()->related("subscriptions.target");
|
$query = $this->getRecord()->related("subscriptions.target");
|
||||||
|
|
||||||
if($this->getOpennesStatus() === static::OPEN) {
|
if ($this->getOpennesStatus() === static::OPEN) {
|
||||||
$query = $query->where("model", "openvk\\Web\\Models\\Entities\\Club")->order($sort);
|
$query = $query->where("model", "openvk\\Web\\Models\\Entities\\Club")->order($sort);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $query->group("follower");
|
return $query->group("follower");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFollowersCount(): int
|
public function getFollowersCount(): int
|
||||||
{
|
{
|
||||||
return sizeof($this->getFollowersQuery());
|
return sizeof($this->getFollowersQuery());
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFollowers(int $page = 1, int $perPage = 6, string $sort = "follower ASC"): \Traversable
|
public function getFollowers(int $page = 1, int $perPage = 6, string $sort = "follower ASC"): \Traversable
|
||||||
{
|
{
|
||||||
$rels = $this->getFollowersQuery($sort)->page($page, $perPage);
|
$rels = $this->getFollowersQuery($sort)->page($page, $perPage);
|
||||||
|
|
||||||
foreach($rels as $rel) {
|
foreach ($rels as $rel) {
|
||||||
$rel = (new Users)->get($rel->follower);
|
$rel = (new Users())->get($rel->follower);
|
||||||
if(!$rel) continue;
|
if (!$rel) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
yield $rel;
|
yield $rel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSuggestedPostsCount(User $user = NULL)
|
public function getSuggestedPostsCount(User $user = null)
|
||||||
{
|
{
|
||||||
$count = 0;
|
$count = 0;
|
||||||
|
|
||||||
if(is_null($user))
|
if (is_null($user)) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if($this->canBeModifiedBy($user))
|
if ($this->canBeModifiedBy($user)) {
|
||||||
$count = (new Posts)->getSuggestedPostsCount($this->getId());
|
$count = (new Posts())->getSuggestedPostsCount($this->getId());
|
||||||
else
|
} else {
|
||||||
$count = (new Posts)->getSuggestedPostsCountByUser($this->getId(), $user->getId());
|
$count = (new Posts())->getSuggestedPostsCountByUser($this->getId(), $user->getId());
|
||||||
|
}
|
||||||
|
|
||||||
return $count;
|
return $count;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getManagers(int $page = 1, bool $ignoreHidden = false): \Traversable
|
public function getManagers(int $page = 1, bool $ignoreHidden = false): \Traversable
|
||||||
{
|
{
|
||||||
$rels = $this->getRecord()->related("group_coadmins.club")->page($page, 6);
|
$rels = $this->getRecord()->related("group_coadmins.club")->page($page, 6);
|
||||||
if($ignoreHidden)
|
if ($ignoreHidden) {
|
||||||
$rels = $rels->where("hidden", false);
|
$rels = $rels->where("hidden", false);
|
||||||
|
}
|
||||||
foreach($rels as $rel) {
|
|
||||||
$rel = (new Managers)->get($rel->id);
|
foreach ($rels as $rel) {
|
||||||
if(!$rel) continue;
|
$rel = (new Managers())->get($rel->id);
|
||||||
|
if (!$rel) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
yield $rel;
|
yield $rel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getManager(User $user, bool $ignoreHidden = false): ?Manager
|
public function getManager(User $user, bool $ignoreHidden = false): ?Manager
|
||||||
{
|
{
|
||||||
$manager = (new Managers)->getByUserAndClub($user->getId(), $this->getId());
|
$manager = (new Managers())->getByUserAndClub($user->getId(), $this->getId());
|
||||||
|
|
||||||
if ($ignoreHidden && $manager !== NULL && $manager->isHidden())
|
if ($ignoreHidden && $manager !== null && $manager->isHidden()) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return $manager;
|
return $manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getManagersCount(bool $ignoreHidden = false): int
|
public function getManagersCount(bool $ignoreHidden = false): int
|
||||||
{
|
{
|
||||||
if($ignoreHidden)
|
if ($ignoreHidden) {
|
||||||
return sizeof($this->getRecord()->related("group_coadmins.club")->where("hidden", false)) + (int) !$this->isOwnerHidden();
|
return sizeof($this->getRecord()->related("group_coadmins.club")->where("hidden", false)) + (int) !$this->isOwnerHidden();
|
||||||
|
}
|
||||||
|
|
||||||
return sizeof($this->getRecord()->related("group_coadmins.club")) + 1;
|
return sizeof($this->getRecord()->related("group_coadmins.club")) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addManager(User $user, ?string $comment = NULL): void
|
public function addManager(User $user, ?string $comment = null): void
|
||||||
{
|
{
|
||||||
DB::i()->getContext()->table("group_coadmins")->insert([
|
DB::i()->getContext()->table("group_coadmins")->insert([
|
||||||
"club" => $this->getId(),
|
"club" => $this->getId(),
|
||||||
|
@ -370,103 +399,107 @@ class Club extends RowModel
|
||||||
"comment" => $comment,
|
"comment" => $comment,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeManager(User $user): void
|
public function removeManager(User $user): void
|
||||||
{
|
{
|
||||||
DB::i()->getContext()->table("group_coadmins")->where([
|
DB::i()->getContext()->table("group_coadmins")->where([
|
||||||
"club" => $this->getId(),
|
"club" => $this->getId(),
|
||||||
"user" => $user->getId(),
|
"user" => $user->getId(),
|
||||||
])->delete();
|
])->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBeModifiedBy(User $user): bool
|
public function canBeModifiedBy(User $user): bool
|
||||||
{
|
{
|
||||||
$id = $user->getId();
|
$id = $user->getId();
|
||||||
if($this->getOwner()->getId() === $id)
|
if ($this->getOwner()->getId() === $id) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return !is_null($this->getRecord()->related("group_coadmins.club")->where("user", $id)->fetch());
|
return !is_null($this->getRecord()->related("group_coadmins.club")->where("user", $id)->fetch());
|
||||||
}
|
}
|
||||||
|
|
||||||
function getWebsite(): ?string
|
public function getWebsite(): ?string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->website;
|
return $this->getRecord()->website;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ban(string $reason): void
|
public function ban(string $reason): void
|
||||||
{
|
{
|
||||||
$this->setBlock_Reason($reason);
|
$this->setBlock_Reason($reason);
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
function unban(): void
|
public function unban(): void
|
||||||
{
|
{
|
||||||
$this->setBlock_Reason(null);
|
$this->setBlock_Reason(null);
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBeViewedBy(?User $user = NULL)
|
public function canBeViewedBy(?User $user = null)
|
||||||
{
|
{
|
||||||
return is_null($this->getBanReason());
|
return is_null($this->getBanReason());
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAlert(): ?string
|
public function getAlert(): ?string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->alert;
|
return $this->getRecord()->alert;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRealId(): int
|
public function getRealId(): int
|
||||||
{
|
{
|
||||||
return $this->getId() * -1;
|
return $this->getId() * -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isEveryoneCanUploadAudios(): bool
|
public function isEveryoneCanUploadAudios(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->everyone_can_upload_audios;
|
return (bool) $this->getRecord()->everyone_can_upload_audios;
|
||||||
}
|
}
|
||||||
|
|
||||||
function canUploadAudio(?User $user): bool
|
public function canUploadAudio(?User $user): bool
|
||||||
{
|
{
|
||||||
if(!$user)
|
if (!$user) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->isEveryoneCanUploadAudios() || $this->canBeModifiedBy($user);
|
return $this->isEveryoneCanUploadAudios() || $this->canBeModifiedBy($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
function canUploadDocs(?User $user): bool
|
public function canUploadDocs(?User $user): bool
|
||||||
{
|
{
|
||||||
if(!$user)
|
if (!$user) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->canBeModifiedBy($user);
|
return $this->canBeModifiedBy($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAudiosCollectionSize()
|
public function getAudiosCollectionSize()
|
||||||
{
|
{
|
||||||
return (new \openvk\Web\Models\Repositories\Audios)->getClubCollectionSize($this);
|
return (new \openvk\Web\Models\Repositories\Audios())->getClubCollectionSize($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toVkApiStruct(?User $user = NULL, string $fields = ''): object
|
public function toVkApiStruct(?User $user = null, string $fields = ''): object
|
||||||
{
|
{
|
||||||
$res = (object) [];
|
$res = (object) [];
|
||||||
|
|
||||||
$res->id = $this->getId();
|
$res->id = $this->getId();
|
||||||
$res->name = $this->getName();
|
$res->name = $this->getName();
|
||||||
$res->screen_name = $this->getShortCode() ?? "club".$this->getId();
|
$res->screen_name = $this->getShortCode() ?? "club" . $this->getId();
|
||||||
$res->is_closed = false;
|
$res->is_closed = false;
|
||||||
$res->type = 'group';
|
$res->type = 'group';
|
||||||
$res->is_member = $user ? (int)$this->getSubscriptionStatus($user) : 0;
|
$res->is_member = $user ? (int) $this->getSubscriptionStatus($user) : 0;
|
||||||
$res->deactivated = NULL;
|
$res->deactivated = null;
|
||||||
$res->can_access_closed = true;
|
$res->can_access_closed = true;
|
||||||
|
|
||||||
if(!is_array($fields))
|
if (!is_array($fields)) {
|
||||||
$fields = explode(',', $fields);
|
$fields = explode(',', $fields);
|
||||||
|
}
|
||||||
|
|
||||||
$avatar_photo = $this->getAvatarPhoto();
|
$avatar_photo = $this->getAvatarPhoto();
|
||||||
foreach($fields as $field) {
|
foreach ($fields as $field) {
|
||||||
switch($field) {
|
switch ($field) {
|
||||||
case 'verified':
|
case 'verified':
|
||||||
$res->verified = (int)$this->isVerified();
|
$res->verified = (int) $this->isVerified();
|
||||||
break;
|
break;
|
||||||
case 'site':
|
case 'site':
|
||||||
$res->site = $this->getWebsite();
|
$res->site = $this->getWebsite();
|
||||||
|
@ -500,9 +533,4 @@ class Club extends RowModel
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
use Traits\TBackDrops;
|
|
||||||
use Traits\TSubscribable;
|
|
||||||
use Traits\TAudioStatuses;
|
|
||||||
use Traits\TIgnorable;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Models\Repositories\Clubs;
|
use openvk\Web\Models\Repositories\Clubs;
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Models\Entities\{Note};
|
use openvk\Web\Models\Entities\{Note};
|
||||||
|
@ -8,61 +12,64 @@ class Comment extends Post
|
||||||
{
|
{
|
||||||
protected $tableName = "comments";
|
protected $tableName = "comments";
|
||||||
protected $upperNodeReferenceColumnName = "owner";
|
protected $upperNodeReferenceColumnName = "owner";
|
||||||
|
|
||||||
function getPrettyId(): string
|
public function getPrettyId(): string
|
||||||
{
|
{
|
||||||
return (string)$this->getRecord()->id;
|
return (string) $this->getRecord()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVirtualId(): int
|
public function getVirtualId(): int
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTarget(): ?Postable
|
public function getTarget(): ?Postable
|
||||||
{
|
{
|
||||||
$entityClassName = $this->getRecord()->model;
|
$entityClassName = $this->getRecord()->model;
|
||||||
$repoClassName = str_replace("Entities", "Repositories", $entityClassName) . "s";
|
$repoClassName = str_replace("Entities", "Repositories", $entityClassName) . "s";
|
||||||
$entity = (new $repoClassName)->get($this->getRecord()->target);
|
$entity = (new $repoClassName())->get($this->getRecord()->target);
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPageURL(): string
|
public function getPageURL(): string
|
||||||
{
|
{
|
||||||
return '#';
|
return '#';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* May return fake owner (group), if flags are [1, (*)]
|
* May return fake owner (group), if flags are [1, (*)]
|
||||||
*
|
*
|
||||||
* @param bool $honourFlags - check flags
|
* @param bool $honourFlags - check flags
|
||||||
*/
|
*/
|
||||||
function getOwner(bool $honourFlags = true, bool $real = false): RowModel
|
public function getOwner(bool $honourFlags = true, bool $real = false): RowModel
|
||||||
{
|
{
|
||||||
if($honourFlags && $this->isPostedOnBehalfOfGroup()) {
|
if ($honourFlags && $this->isPostedOnBehalfOfGroup()) {
|
||||||
if($this->getTarget() instanceof Post)
|
if ($this->getTarget() instanceof Post) {
|
||||||
return (new Clubs)->get(abs($this->getTarget()->getTargetWall()));
|
return (new Clubs())->get(abs($this->getTarget()->getTargetWall()));
|
||||||
|
}
|
||||||
|
|
||||||
if($this->getTarget() instanceof Topic)
|
if ($this->getTarget() instanceof Topic) {
|
||||||
return $this->getTarget()->getClub();
|
return $this->getTarget()->getClub();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::getOwner($honourFlags, $real);
|
return parent::getOwner($honourFlags, $real);
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBeDeletedBy(User $user = NULL): bool
|
public function canBeDeletedBy(User $user = null): bool
|
||||||
{
|
{
|
||||||
if(!$user)
|
if (!$user) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->getOwner()->getId() == $user->getId() ||
|
return $this->getOwner()->getId() == $user->getId() ||
|
||||||
$this->getTarget()->getOwner()->getId() == $user->getId() ||
|
$this->getTarget()->getOwner()->getId() == $user->getId() ||
|
||||||
$this->getTarget() instanceof Post && $this->getTarget()->getTargetWall() < 0 && (new Clubs)->get(abs($this->getTarget()->getTargetWall()))->canBeModifiedBy($user) ||
|
$this->getTarget() instanceof Post && $this->getTarget()->getTargetWall() < 0 && (new Clubs())->get(abs($this->getTarget()->getTargetWall()))->canBeModifiedBy($user) ||
|
||||||
$this->getTarget() instanceof Topic && $this->getTarget()->canBeModifiedBy($user);
|
$this->getTarget() instanceof Topic && $this->getTarget()->canBeModifiedBy($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toVkApiStruct(?User $user = NULL, bool $need_likes = false, bool $extended = false, ?Note $note = NULL): object
|
public function toVkApiStruct(?User $user = null, bool $need_likes = false, bool $extended = false, ?Note $note = null): object
|
||||||
{
|
{
|
||||||
$res = (object) [];
|
$res = (object) [];
|
||||||
|
|
||||||
|
@ -72,93 +79,97 @@ class Comment extends Post
|
||||||
$res->text = $this->getText(false);
|
$res->text = $this->getText(false);
|
||||||
$res->attachments = [];
|
$res->attachments = [];
|
||||||
$res->parents_stack = [];
|
$res->parents_stack = [];
|
||||||
|
|
||||||
if(!is_null($note)) {
|
if (!is_null($note)) {
|
||||||
$res->uid = $this->getOwner()->getId();
|
$res->uid = $this->getOwner()->getId();
|
||||||
$res->nid = $note->getId();
|
$res->nid = $note->getId();
|
||||||
$res->oid = $note->getOwner()->getId();
|
$res->oid = $note->getOwner()->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($this->getChildren() as $attachment) {
|
foreach ($this->getChildren() as $attachment) {
|
||||||
if($attachment->isDeleted())
|
if ($attachment->isDeleted()) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if($attachment instanceof \openvk\Web\Models\Entities\Photo) {
|
|
||||||
|
if ($attachment instanceof \openvk\Web\Models\Entities\Photo) {
|
||||||
$res->attachments[] = $attachment->toVkApiStruct();
|
$res->attachments[] = $attachment->toVkApiStruct();
|
||||||
} else if($attachment instanceof \openvk\Web\Models\Entities\Video) {
|
} elseif ($attachment instanceof \openvk\Web\Models\Entities\Video) {
|
||||||
$res->attachments[] = $attachment->toVkApiStruct($this->getUser());
|
$res->attachments[] = $attachment->toVkApiStruct($this->getUser());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($need_likes) {
|
if ($need_likes) {
|
||||||
$res->count = $this->getLikesCount();
|
$res->count = $this->getLikesCount();
|
||||||
$res->user_likes = (int)$this->hasLikeFrom($user);
|
$res->user_likes = (int) $this->hasLikeFrom($user);
|
||||||
$res->can_like = 1;
|
$res->can_like = 1;
|
||||||
}
|
}
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getURL(): string
|
public function getURL(): string
|
||||||
{
|
{
|
||||||
return "/wall" . $this->getTarget()->getPrettyId() . "#_comment" . $this->getId();
|
return "/wall" . $this->getTarget()->getPrettyId() . "#_comment" . $this->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBeViewedBy(?User $user = NULL): bool
|
public function canBeViewedBy(?User $user = null): bool
|
||||||
{
|
{
|
||||||
if($this->isDeleted() || $this->getTarget()->isDeleted()) {
|
if ($this->isDeleted() || $this->getTarget()->isDeleted()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->getTarget()->canBeViewedBy($user);
|
return $this->getTarget()->canBeViewedBy($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isFromPostAuthor($target = NULL)
|
public function isFromPostAuthor($target = null)
|
||||||
{
|
{
|
||||||
if(!$target)
|
if (!$target) {
|
||||||
$target = $this->getTarget();
|
$target = $this->getTarget();
|
||||||
|
}
|
||||||
|
|
||||||
$target_owner = $target->getOwner();
|
$target_owner = $target->getOwner();
|
||||||
$comment_owner = $this->getOwner();
|
$comment_owner = $this->getOwner();
|
||||||
|
|
||||||
if($target_owner->getRealId() === $comment_owner->getRealId())
|
if ($target_owner->getRealId() === $comment_owner->getRealId()) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
# TODO: make it work with signer_id
|
# TODO: make it work with signer_id
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toNotifApiStruct()
|
public function toNotifApiStruct()
|
||||||
{
|
{
|
||||||
$res = (object)[];
|
$res = (object) [];
|
||||||
|
|
||||||
$res->id = $this->getId();
|
$res->id = $this->getId();
|
||||||
$res->owner_id = $this->getOwner()->getId();
|
$res->owner_id = $this->getOwner()->getId();
|
||||||
$res->date = $this->getPublicationTime()->timestamp();
|
$res->date = $this->getPublicationTime()->timestamp();
|
||||||
$res->text = $this->getText(false);
|
$res->text = $this->getText(false);
|
||||||
$res->post = NULL; # todo
|
$res->post = null; # todo
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBeEditedBy(?User $user = NULL): bool
|
public function canBeEditedBy(?User $user = null): bool
|
||||||
{
|
{
|
||||||
if(!$user)
|
if (!$user) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return $user->getId() == $this->getOwner(false)->getId();
|
return $user->getId() == $this->getOwner(false)->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTargetURL(): string
|
public function getTargetURL(): string
|
||||||
{
|
{
|
||||||
$target = $this->getTarget();
|
$target = $this->getTarget();
|
||||||
$target_name = 'wall';
|
$target_name = 'wall';
|
||||||
|
|
||||||
if(!$target) {
|
if (!$target) {
|
||||||
return '/404';
|
return '/404';
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(get_class($target)) {
|
switch (get_class($target)) {
|
||||||
case 'openvk\Web\Models\Entities\Note':
|
case 'openvk\Web\Models\Entities\Note':
|
||||||
$target_name = 'note';
|
$target_name = 'note';
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use Chandler\Database\DatabaseConnection;
|
use Chandler\Database\DatabaseConnection;
|
||||||
use Chandler\Signaling\SignalManager;
|
use Chandler\Signaling\SignalManager;
|
||||||
use Chandler\Security\Authenticator;
|
use Chandler\Security\Authenticator;
|
||||||
|
@ -12,7 +16,7 @@ use Nette\Database\Table\ActiveRow;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A repository of messages sent between correspondents.
|
* A repository of messages sent between correspondents.
|
||||||
*
|
*
|
||||||
* A pseudo-repository that operates with messages
|
* A pseudo-repository that operates with messages
|
||||||
* sent between users.
|
* sent between users.
|
||||||
*/
|
*/
|
||||||
|
@ -26,136 +30,141 @@ class Correspondence
|
||||||
* @var \Nette\Database\Table\Selection Messages table
|
* @var \Nette\Database\Table\Selection Messages table
|
||||||
*/
|
*/
|
||||||
private $messages;
|
private $messages;
|
||||||
|
|
||||||
const CAP_BEHAVIOUR_END_MESSAGE_ID = 1;
|
public const CAP_BEHAVIOUR_END_MESSAGE_ID = 1;
|
||||||
const CAP_BEHAVIOUR_START_MESSAGE_ID = 2;
|
public const CAP_BEHAVIOUR_START_MESSAGE_ID = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Correspondence constructor.
|
* Correspondence constructor.
|
||||||
*
|
*
|
||||||
* Requires two users/clubs to construct.
|
* Requires two users/clubs to construct.
|
||||||
*
|
*
|
||||||
* @param $correspondent - first correspondent
|
* @param $correspondent - first correspondent
|
||||||
* @param $anotherCorrespondents - another correspondent
|
* @param $anotherCorrespondents - another correspondent
|
||||||
*/
|
*/
|
||||||
function __construct(RowModel $correspondent, RowModel $anotherCorrespondent)
|
public function __construct(RowModel $correspondent, RowModel $anotherCorrespondent)
|
||||||
{
|
{
|
||||||
$this->correspondents = [$correspondent, $anotherCorrespondent];
|
$this->correspondents = [$correspondent, $anotherCorrespondent];
|
||||||
$this->messages = DatabaseConnection::i()->getContext()->table("messages");
|
$this->messages = DatabaseConnection::i()->getContext()->table("messages");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get /im?sel url.
|
* Get /im?sel url.
|
||||||
*
|
*
|
||||||
* @returns string - URL
|
* @returns string - URL
|
||||||
*/
|
*/
|
||||||
function getURL(): string
|
public function getURL(): string
|
||||||
{
|
{
|
||||||
$id = $this->correspondents[1]->getId();
|
$id = $this->correspondents[1]->getId();
|
||||||
$id = get_class($this->correspondents[1]) === 'openvk\Web\Models\Entities\Club' ? $id * -1 : $id;
|
$id = get_class($this->correspondents[1]) === 'openvk\Web\Models\Entities\Club' ? $id * -1 : $id;
|
||||||
|
|
||||||
return "/im?sel=$id";
|
return "/im?sel=$id";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getID(): int
|
public function getID(): int
|
||||||
{
|
{
|
||||||
$id = $this->correspondents[1]->getId();
|
$id = $this->correspondents[1]->getId();
|
||||||
$id = get_class($this->correspondents[1]) === 'openvk\Web\Models\Entities\Club' ? $id * -1 : $id;
|
$id = get_class($this->correspondents[1]) === 'openvk\Web\Models\Entities\Club' ? $id * -1 : $id;
|
||||||
|
|
||||||
return $id;
|
return $id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get correspondents as array.
|
* Get correspondents as array.
|
||||||
*
|
*
|
||||||
* @returns RowModel[] Array of correspondents (usually two)
|
* @returns RowModel[] Array of correspondents (usually two)
|
||||||
*/
|
*/
|
||||||
function getCorrespondents(): array
|
public function getCorrespondents(): array
|
||||||
{
|
{
|
||||||
return $this->correspondents;
|
return $this->correspondents;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch messages.
|
* Fetch messages.
|
||||||
*
|
*
|
||||||
* Fetch messages on per page basis.
|
* Fetch messages on per page basis.
|
||||||
*
|
*
|
||||||
* @param $cap - page (defaults to first)
|
* @param $cap - page (defaults to first)
|
||||||
* @param $limit - messages per page (defaults to default per page count)
|
* @param $limit - messages per page (defaults to default per page count)
|
||||||
* @returns \Traversable - iterable messages cursor
|
* @returns \Traversable - iterable messages cursor
|
||||||
*/
|
*/
|
||||||
function getMessages(int $capBehavior = 1, ?int $cap = NULL, ?int $limit = NULL, ?int $padding = NULL, bool $reverse = false): array
|
public function getMessages(int $capBehavior = 1, ?int $cap = null, ?int $limit = null, ?int $padding = null, bool $reverse = false): array
|
||||||
{
|
{
|
||||||
$query = file_get_contents(__DIR__ . "/../sql/get-messages.tsql");
|
$query = file_get_contents(__DIR__ . "/../sql/get-messages.tsql");
|
||||||
$params = [
|
$params = [
|
||||||
[get_class($this->correspondents[0]), get_class($this->correspondents[1])],
|
[get_class($this->correspondents[0]), get_class($this->correspondents[1])],
|
||||||
[$this->correspondents[0]->getId(), $this->correspondents[1]->getId()],
|
[$this->correspondents[0]->getId(), $this->correspondents[1]->getId()],
|
||||||
[$limit ?? OPENVK_DEFAULT_PER_PAGE]
|
[$limit ?? OPENVK_DEFAULT_PER_PAGE],
|
||||||
];
|
];
|
||||||
$params = array_merge($params[0], $params[1], array_reverse($params[0]), array_reverse($params[1]), $params[2]);
|
$params = array_merge($params[0], $params[1], array_reverse($params[0]), array_reverse($params[1]), $params[2]);
|
||||||
|
|
||||||
if ($limit === NULL)
|
if ($limit === null) {
|
||||||
DatabaseConnection::i()->getConnection()->query("UPDATE messages SET unread = 0 WHERE sender_id = ".$this->correspondents[1]->getId());
|
DatabaseConnection::i()->getConnection()->query("UPDATE messages SET unread = 0 WHERE sender_id = " . $this->correspondents[1]->getId());
|
||||||
|
}
|
||||||
if(is_null($cap)) {
|
|
||||||
|
if (is_null($cap)) {
|
||||||
$query = str_replace("\n AND (`id` > ?)", "", $query);
|
$query = str_replace("\n AND (`id` > ?)", "", $query);
|
||||||
} else {
|
} else {
|
||||||
if($capBehavior === 1)
|
if ($capBehavior === 1) {
|
||||||
$query = str_replace("\n AND (`id` > ?)", "\n AND (`id` < ?)", $query);
|
$query = str_replace("\n AND (`id` > ?)", "\n AND (`id` < ?)", $query);
|
||||||
|
}
|
||||||
|
|
||||||
array_unshift($params, $cap);
|
array_unshift($params, $cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_null($padding))
|
if (is_null($padding)) {
|
||||||
$query = str_replace("\nOFFSET\n?", "", $query);
|
$query = str_replace("\nOFFSET\n?", "", $query);
|
||||||
else
|
} else {
|
||||||
$params[] = $padding;
|
$params[] = $padding;
|
||||||
|
}
|
||||||
if($reverse)
|
|
||||||
|
if ($reverse) {
|
||||||
$query = str_replace("`created` DESC", "`created` ASC", $query);
|
$query = str_replace("`created` DESC", "`created` ASC", $query);
|
||||||
|
}
|
||||||
|
|
||||||
$msgs = DatabaseConnection::i()->getConnection()->query($query, ...$params);
|
$msgs = DatabaseConnection::i()->getConnection()->query($query, ...$params);
|
||||||
$msgs = array_map(function($message) {
|
$msgs = array_map(function ($message) {
|
||||||
$message = new ActiveRow((array) $message, $this->messages); #Directly creating ActiveRow is faster than making query
|
$message = new ActiveRow((array) $message, $this->messages); #Directly creating ActiveRow is faster than making query
|
||||||
|
|
||||||
return new Message($message);
|
return new Message($message);
|
||||||
}, iterator_to_array($msgs));
|
}, iterator_to_array($msgs));
|
||||||
|
|
||||||
return $msgs;
|
return $msgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get last message from correspondence.
|
* Get last message from correspondence.
|
||||||
*
|
*
|
||||||
* @returns Message|null - message, if any
|
* @returns Message|null - message, if any
|
||||||
*/
|
*/
|
||||||
function getPreviewMessage(): ?Message
|
public function getPreviewMessage(): ?Message
|
||||||
{
|
{
|
||||||
$messages = $this->getMessages(1, NULL, 1, 0);
|
$messages = $this->getMessages(1, null, 1, 0);
|
||||||
return $messages[0] ?? NULL;
|
return $messages[0] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send message.
|
* Send message.
|
||||||
*
|
*
|
||||||
* @deprecated
|
* @deprecated
|
||||||
* @returns Message|false - resulting message, or false in case of non-successful transaction
|
* @returns Message|false - resulting message, or false in case of non-successful transaction
|
||||||
*/
|
*/
|
||||||
function sendMessage(Message $message, bool $dontReverse = false)
|
public function sendMessage(Message $message, bool $dontReverse = false)
|
||||||
{
|
{
|
||||||
if(!$dontReverse) {
|
if (!$dontReverse) {
|
||||||
$user = (new Users)->getByChandlerUser(Authenticator::i()->getUser());
|
$user = (new Users())->getByChandlerUser(Authenticator::i()->getUser());
|
||||||
if(!$user)
|
if (!$user) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$ids = [$this->correspondents[0]->getId(), $this->correspondents[1]->getId()];
|
$ids = [$this->correspondents[0]->getId(), $this->correspondents[1]->getId()];
|
||||||
$classes = [get_class($this->correspondents[0]), get_class($this->correspondents[1])];
|
$classes = [get_class($this->correspondents[0]), get_class($this->correspondents[1])];
|
||||||
if(!$dontReverse && $ids[1] === $user->getId()) {
|
if (!$dontReverse && $ids[1] === $user->getId()) {
|
||||||
$ids = array_reverse($ids);
|
$ids = array_reverse($ids);
|
||||||
$classes = array_reverse($classes);
|
$classes = array_reverse($classes);
|
||||||
}
|
}
|
||||||
|
|
||||||
$message->setSender_Id($ids[0]);
|
$message->setSender_Id($ids[0]);
|
||||||
$message->setRecipient_Id($ids[1]);
|
$message->setRecipient_Id($ids[1]);
|
||||||
$message->setSender_Type($classes[0]);
|
$message->setSender_Type($classes[0]);
|
||||||
|
@ -163,15 +172,15 @@ class Correspondence
|
||||||
$message->setCreated(time());
|
$message->setCreated(time());
|
||||||
$message->setUnread(1);
|
$message->setUnread(1);
|
||||||
$message->save();
|
$message->save();
|
||||||
|
|
||||||
DatabaseConnection::i()->getConnection()->query("UPDATE messages SET unread = 0 WHERE sender_id = ".$this->correspondents[1]->getId());
|
DatabaseConnection::i()->getConnection()->query("UPDATE messages SET unread = 0 WHERE sender_id = " . $this->correspondents[1]->getId());
|
||||||
|
|
||||||
# да
|
# да
|
||||||
if($ids[0] !== $ids[1]) {
|
if ($ids[0] !== $ids[1]) {
|
||||||
$event = new NewMessageEvent($message);
|
$event = new NewMessageEvent($message);
|
||||||
(SignalManager::i())->triggerEvent($event, $ids[1]);
|
(SignalManager::i())->triggerEvent($event, $ids[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $message;
|
return $message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Models\Repositories\{Clubs, Users, Photos};
|
use openvk\Web\Models\Repositories\{Clubs, Users, Photos};
|
||||||
use openvk\Web\Models\Entities\{Photo};
|
use openvk\Web\Models\Entities\{Photo};
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
|
@ -10,45 +14,46 @@ class Document extends Media
|
||||||
{
|
{
|
||||||
protected $tableName = "documents";
|
protected $tableName = "documents";
|
||||||
protected $fileExtension = "gif";
|
protected $fileExtension = "gif";
|
||||||
private $tmp_format = NULL;
|
private $tmp_format = null;
|
||||||
|
|
||||||
const VKAPI_TYPE_TEXT = 1;
|
public const VKAPI_TYPE_TEXT = 1;
|
||||||
const VKAPI_TYPE_ARCHIVE = 2;
|
public const VKAPI_TYPE_ARCHIVE = 2;
|
||||||
const VKAPI_TYPE_GIF = 3;
|
public const VKAPI_TYPE_GIF = 3;
|
||||||
const VKAPI_TYPE_IMAGE = 4;
|
public const VKAPI_TYPE_IMAGE = 4;
|
||||||
const VKAPI_TYPE_AUDIO = 5;
|
public const VKAPI_TYPE_AUDIO = 5;
|
||||||
const VKAPI_TYPE_VIDEO = 6;
|
public const VKAPI_TYPE_VIDEO = 6;
|
||||||
const VKAPI_TYPE_BOOKS = 7;
|
public const VKAPI_TYPE_BOOKS = 7;
|
||||||
const VKAPI_TYPE_UNKNOWN = 8;
|
public const VKAPI_TYPE_UNKNOWN = 8;
|
||||||
|
|
||||||
const VKAPI_FOLDER_PRIVATE = 0;
|
public const VKAPI_FOLDER_PRIVATE = 0;
|
||||||
const VKAPI_FOLDER_STUDY = 1;
|
public const VKAPI_FOLDER_STUDY = 1;
|
||||||
const VKAPI_FOLDER_BOOK = 2;
|
public const VKAPI_FOLDER_BOOK = 2;
|
||||||
const VKAPI_FOLDER_PUBLIC = 3;
|
public const VKAPI_FOLDER_PUBLIC = 3;
|
||||||
|
|
||||||
protected function pathFromHash(string $hash): string
|
protected function pathFromHash(string $hash): string
|
||||||
{
|
{
|
||||||
$dir = $this->getBaseDir() . substr($hash, 0, 2);
|
$dir = $this->getBaseDir() . substr($hash, 0, 2);
|
||||||
if(!is_dir($dir))
|
if (!is_dir($dir)) {
|
||||||
mkdir($dir);
|
mkdir($dir);
|
||||||
|
}
|
||||||
|
|
||||||
return "$dir/$hash." . $this->getFileExtension();
|
return "$dir/$hash." . $this->getFileExtension();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getURL(): string
|
public function getURL(): string
|
||||||
{
|
{
|
||||||
$hash = $this->getRecord()->hash;
|
$hash = $this->getRecord()->hash;
|
||||||
$filetype = $this->getFileExtension();
|
$filetype = $this->getFileExtension();
|
||||||
|
|
||||||
switch(OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["mode"]) {
|
switch (OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["mode"]) {
|
||||||
default:
|
default:
|
||||||
case "default":
|
case "default":
|
||||||
case "basic":
|
case "basic":
|
||||||
return "http://" . $_SERVER['HTTP_HOST'] . "/blob_" . substr($hash, 0, 2) . "/$hash.$filetype";
|
return "http://" . $_SERVER['HTTP_HOST'] . "/blob_" . substr($hash, 0, 2) . "/$hash.$filetype";
|
||||||
break;
|
break;
|
||||||
case "accelerated":
|
case "accelerated":
|
||||||
return "http://" . $_SERVER['HTTP_HOST'] . "/openvk-datastore/$hash.$filetype";
|
return "http://" . $_SERVER['HTTP_HOST'] . "/openvk-datastore/$hash.$filetype";
|
||||||
break;
|
break;
|
||||||
case "server":
|
case "server":
|
||||||
$settings = (object) OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["server"];
|
$settings = (object) OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["server"];
|
||||||
return (
|
return (
|
||||||
|
@ -57,7 +62,7 @@ class Document extends Media
|
||||||
$settings->path .
|
$settings->path .
|
||||||
substr($hash, 0, 2) . "/$hash.$filetype"
|
substr($hash, 0, 2) . "/$hash.$filetype"
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +74,7 @@ class Document extends Media
|
||||||
|
|
||||||
protected function makePreview(string $tmp_name, string $filename, int $owner): bool
|
protected function makePreview(string $tmp_name, string $filename, int $owner): bool
|
||||||
{
|
{
|
||||||
$preview_photo = new Photo;
|
$preview_photo = new Photo();
|
||||||
$preview_photo->setOwner($owner);
|
$preview_photo->setOwner($owner);
|
||||||
$preview_photo->setDescription("internal use");
|
$preview_photo->setDescription("internal use");
|
||||||
$preview_photo->setCreated(time());
|
$preview_photo->setCreated(time());
|
||||||
|
@ -79,7 +84,7 @@ class Document extends Media
|
||||||
"error" => 0,
|
"error" => 0,
|
||||||
]);
|
]);
|
||||||
$preview_photo->save();
|
$preview_photo->save();
|
||||||
$this->stateChanges("preview", "photo_".$preview_photo->getId());
|
$this->stateChanges("preview", "photo_" . $preview_photo->getId());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -90,25 +95,29 @@ class Document extends Media
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setFile(array $file): void
|
public function setFile(array $file): void
|
||||||
{
|
{
|
||||||
if($file["error"] !== UPLOAD_ERR_OK)
|
if ($file["error"] !== UPLOAD_ERR_OK) {
|
||||||
throw new ISE("File uploaded is corrupted");
|
throw new ISE("File uploaded is corrupted");
|
||||||
|
}
|
||||||
|
|
||||||
$original_name = $file["name"];
|
$original_name = $file["name"];
|
||||||
$file_format = end(explode(".", $original_name));
|
$file_format = end(explode(".", $original_name));
|
||||||
$file_size = $file["size"];
|
$file_size = $file["size"];
|
||||||
$type = Document::detectTypeByFormat($file_format);
|
$type = Document::detectTypeByFormat($file_format);
|
||||||
|
|
||||||
if(!$file_format)
|
if (!$file_format) {
|
||||||
throw new \TypeError("No file format");
|
throw new \TypeError("No file format");
|
||||||
|
}
|
||||||
|
|
||||||
if(!in_array(mb_strtolower($file_format), OPENVK_ROOT_CONF["openvk"]["preferences"]["docs"]["allowedFormats"]))
|
if (!in_array(mb_strtolower($file_format), OPENVK_ROOT_CONF["openvk"]["preferences"]["docs"]["allowedFormats"])) {
|
||||||
throw new \TypeError("Forbidden file format");
|
throw new \TypeError("Forbidden file format");
|
||||||
|
}
|
||||||
|
|
||||||
if($file_size < 1 || $file_size > (OPENVK_ROOT_CONF["openvk"]["preferences"]["docs"]["maxSize"] * 1024 * 1024))
|
if ($file_size < 1 || $file_size > (OPENVK_ROOT_CONF["openvk"]["preferences"]["docs"]["maxSize"] * 1024 * 1024)) {
|
||||||
throw new \ValueError("Invalid filesize");
|
throw new \ValueError("Invalid filesize");
|
||||||
|
}
|
||||||
|
|
||||||
$hash = hash_file("whirlpool", $file["tmp_name"]);
|
$hash = hash_file("whirlpool", $file["tmp_name"]);
|
||||||
$this->stateChanges("original_name", ovk_proc_strtr($original_name, 255));
|
$this->stateChanges("original_name", ovk_proc_strtr($original_name, 255));
|
||||||
|
@ -119,76 +128,78 @@ class Document extends Media
|
||||||
$this->stateChanges("access_key", bin2hex(random_bytes(9)));
|
$this->stateChanges("access_key", bin2hex(random_bytes(9)));
|
||||||
$this->stateChanges("type", $type);
|
$this->stateChanges("type", $type);
|
||||||
|
|
||||||
if(in_array($type, [3, 4])) {
|
if (in_array($type, [3, 4])) {
|
||||||
$this->makePreview($file["tmp_name"], $original_name, $file["preview_owner"]);
|
$this->makePreview($file["tmp_name"], $original_name, $file["preview_owner"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->saveFile($file["tmp_name"], $hash);
|
$this->saveFile($file["tmp_name"], $hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasPreview(): bool
|
public function hasPreview(): bool
|
||||||
{
|
{
|
||||||
return $this->getRecord()->preview != NULL;
|
return $this->getRecord()->preview != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isOwnerHidden(): bool
|
public function isOwnerHidden(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->owner_hidden;
|
return (bool) $this->getRecord()->owner_hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isCopy(): bool
|
public function isCopy(): bool
|
||||||
{
|
{
|
||||||
return $this->getRecord()->copy_of != NULL;
|
return $this->getRecord()->copy_of != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isLicensed(): bool
|
public function isLicensed(): bool
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isUnsafe(): bool
|
public function isUnsafe(): bool
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAnonymous(): bool
|
public function isAnonymous(): bool
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPrivate(): bool
|
public function isPrivate(): bool
|
||||||
{
|
{
|
||||||
return $this->getFolder() == Document::VKAPI_FOLDER_PRIVATE;
|
return $this->getFolder() == Document::VKAPI_FOLDER_PRIVATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isImage(): bool
|
public function isImage(): bool
|
||||||
{
|
{
|
||||||
return in_array($this->getVKAPIType(), [3, 4]);
|
return in_array($this->getVKAPIType(), [3, 4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isBook(): bool
|
public function isBook(): bool
|
||||||
{
|
{
|
||||||
return in_array($this->getFileExtension(), ["pdf"]);
|
return in_array($this->getFileExtension(), ["pdf"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAudio(): bool
|
public function isAudio(): bool
|
||||||
{
|
{
|
||||||
return in_array($this->getVKAPIType(), [Document::VKAPI_TYPE_AUDIO]);
|
return in_array($this->getVKAPIType(), [Document::VKAPI_TYPE_AUDIO]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isGif(): bool
|
public function isGif(): bool
|
||||||
{
|
{
|
||||||
return $this->getVKAPIType() == 3;
|
return $this->getVKAPIType() == 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isCopiedBy($user = NULL): bool
|
public function isCopiedBy($user = null): bool
|
||||||
{
|
{
|
||||||
if(!$user)
|
if (!$user) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if($user->getRealId() === $this->getOwnerID())
|
if ($user->getRealId() === $this->getOwnerID()) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return DatabaseConnection::i()->getContext()->table("documents")->where([
|
return DatabaseConnection::i()->getContext()->table("documents")->where([
|
||||||
"owner" => $user->getRealId(),
|
"owner" => $user->getRealId(),
|
||||||
"copy_of" => $this->getId(),
|
"copy_of" => $this->getId(),
|
||||||
|
@ -196,19 +207,19 @@ class Document extends Media
|
||||||
])->count() > 0;
|
])->count() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function copy(User $user): Document
|
public function copy(User $user): Document
|
||||||
{
|
{
|
||||||
$item = DatabaseConnection::i()->getContext()->table("documents")->where([
|
$item = DatabaseConnection::i()->getContext()->table("documents")->where([
|
||||||
"owner" => $user->getId(),
|
"owner" => $user->getId(),
|
||||||
"copy_of" => $this->getId(),
|
"copy_of" => $this->getId(),
|
||||||
]);
|
]);
|
||||||
if($item->count() > 0) {
|
if ($item->count() > 0) {
|
||||||
$older = new Document($item->fetch());
|
$older = new Document($item->fetch());
|
||||||
}
|
}
|
||||||
|
|
||||||
$this_document_array = $this->getRecord()->toArray();
|
$this_document_array = $this->getRecord()->toArray();
|
||||||
|
|
||||||
$new_document = new Document;
|
$new_document = new Document();
|
||||||
$new_document->setOwner($user->getId());
|
$new_document->setOwner($user->getId());
|
||||||
$new_document->updateHash($this_document_array["hash"]);
|
$new_document->updateHash($this_document_array["hash"]);
|
||||||
$new_document->setOwner_hidden(1);
|
$new_document->setOwner_hidden(1);
|
||||||
|
@ -228,21 +239,21 @@ class Document extends Media
|
||||||
return $new_document;
|
return $new_document;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setTags(?string $tags): bool
|
public function setTags(?string $tags): bool
|
||||||
{
|
{
|
||||||
if(is_null($tags)) {
|
if (is_null($tags)) {
|
||||||
$this->stateChanges("tags", NULL);
|
$this->stateChanges("tags", null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$parsed = explode(",", $tags);
|
$parsed = explode(",", $tags);
|
||||||
if(sizeof($parsed) < 1 || $parsed[0] == "") {
|
if (sizeof($parsed) < 1 || $parsed[0] == "") {
|
||||||
$this->stateChanges("tags", NULL);
|
$this->stateChanges("tags", null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = "";
|
$result = "";
|
||||||
foreach($parsed as $tag) {
|
foreach ($parsed as $tag) {
|
||||||
$result .= trim($tag) . ($tag != end($parsed) ? "," : '');
|
$result .= trim($tag) . ($tag != end($parsed) ? "," : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,99 +261,101 @@ class Document extends Media
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOwner(bool $real = false): RowModel
|
public function getOwner(bool $real = false): RowModel
|
||||||
{
|
{
|
||||||
$oid = (int) $this->getRecord()->owner;
|
$oid = (int) $this->getRecord()->owner;
|
||||||
if($oid > 0)
|
if ($oid > 0) {
|
||||||
return (new Users)->get($oid);
|
return (new Users())->get($oid);
|
||||||
else
|
} else {
|
||||||
return (new Clubs)->get($oid * -1);
|
return (new Clubs())->get($oid * -1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFileExtension(): string
|
public function getFileExtension(): string
|
||||||
{
|
{
|
||||||
if($this->tmp_format) {
|
if ($this->tmp_format) {
|
||||||
return $this->tmp_format;
|
return $this->tmp_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->getRecord()->format;
|
return $this->getRecord()->format;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPrettyId(): string
|
public function getPrettyId(): string
|
||||||
{
|
{
|
||||||
return $this->getVirtualId() . "_" . $this->getId();
|
return $this->getVirtualId() . "_" . $this->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPrettiestId(): string
|
public function getPrettiestId(): string
|
||||||
{
|
{
|
||||||
return $this->getVirtualId() . "_" . $this->getId() . "_" . $this->getAccessKey();
|
return $this->getVirtualId() . "_" . $this->getId() . "_" . $this->getAccessKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOriginal(): Document
|
public function getOriginal(): Document
|
||||||
{
|
{
|
||||||
return $this->getRecord()->copy_of;
|
return $this->getRecord()->copy_of;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getName(): string
|
public function getName(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->name;
|
return $this->getRecord()->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOriginalName(): string
|
public function getOriginalName(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->original_name;
|
return $this->getRecord()->original_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVKAPIType(): int
|
public function getVKAPIType(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->type;
|
return $this->getRecord()->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFolder(): int
|
public function getFolder(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->folder_id;
|
return $this->getRecord()->folder_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTags(): array
|
public function getTags(): array
|
||||||
{
|
{
|
||||||
$tags = $this->getRecord()->tags;
|
$tags = $this->getRecord()->tags;
|
||||||
if(!$tags)
|
if (!$tags) {
|
||||||
return [];
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
return explode(",", $tags ?? "");
|
return explode(",", $tags ?? "");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFilesize(): int
|
public function getFilesize(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->filesize;
|
return $this->getRecord()->filesize;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPreview(): ?RowModel
|
public function getPreview(): ?RowModel
|
||||||
{
|
{
|
||||||
$preview_array = $this->getRecord()->preview;
|
$preview_array = $this->getRecord()->preview;
|
||||||
$preview = explode(",", $this->getRecord()->preview)[0];
|
$preview = explode(",", $this->getRecord()->preview)[0];
|
||||||
$model = NULL;
|
$model = null;
|
||||||
$exploded = explode("_", $preview);
|
$exploded = explode("_", $preview);
|
||||||
|
|
||||||
switch($exploded[0]) {
|
switch ($exploded[0]) {
|
||||||
case "photo":
|
case "photo":
|
||||||
$model = (new Photos)->get((int)$exploded[1]);
|
$model = (new Photos())->get((int) $exploded[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $model;
|
return $model;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOwnerID(): int
|
public function getOwnerID(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->owner;
|
return $this->getRecord()->owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toApiPreview(): object
|
public function toApiPreview(): object
|
||||||
{
|
{
|
||||||
$preview = $this->getPreview();
|
$preview = $this->getPreview();
|
||||||
if($preview instanceof Photo) {
|
if ($preview instanceof Photo) {
|
||||||
return (object)[
|
return (object) [
|
||||||
"photo" => [
|
"photo" => [
|
||||||
"sizes" => array_values($preview->getVkApiSizes()),
|
"sizes" => array_values($preview->getVkApiSizes()),
|
||||||
],
|
],
|
||||||
|
@ -350,20 +363,22 @@ class Document extends Media
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBeModifiedBy(User $user = NULL): bool
|
public function canBeModifiedBy(User $user = null): bool
|
||||||
{
|
{
|
||||||
if(!$user)
|
if (!$user) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->getOwnerID() < 0) {
|
||||||
|
return (new Clubs())->get(abs($this->getOwnerID()))->canBeModifiedBy($user);
|
||||||
|
}
|
||||||
|
|
||||||
if($this->getOwnerID() < 0)
|
|
||||||
return (new Clubs)->get(abs($this->getOwnerID()))->canBeModifiedBy($user);
|
|
||||||
|
|
||||||
return $this->getOwnerID() === $user->getId();
|
return $this->getOwnerID() === $user->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function toVkApiStruct(?User $user = NULL, bool $return_tags = false): object
|
public function toVkApiStruct(?User $user = null, bool $return_tags = false): object
|
||||||
{
|
{
|
||||||
$res = new \stdClass;
|
$res = new \stdClass();
|
||||||
$res->id = $this->getId();
|
$res->id = $this->getId();
|
||||||
$res->owner_id = $this->getVirtualId();
|
$res->owner_id = $this->getVirtualId();
|
||||||
$res->title = $this->getName();
|
$res->title = $this->getName();
|
||||||
|
@ -378,30 +393,33 @@ class Document extends Media
|
||||||
$res->folder_id = (int) $this->getFolder();
|
$res->folder_id = (int) $this->getFolder();
|
||||||
$res->access_key = $this->getAccessKey();
|
$res->access_key = $this->getAccessKey();
|
||||||
$res->private_url = "";
|
$res->private_url = "";
|
||||||
if($user)
|
if ($user) {
|
||||||
$res->can_manage = $this->canBeModifiedBy($user);
|
$res->can_manage = $this->canBeModifiedBy($user);
|
||||||
|
}
|
||||||
|
|
||||||
if($this->hasPreview())
|
if ($this->hasPreview()) {
|
||||||
$res->preview = $this->toApiPreview();
|
$res->preview = $this->toApiPreview();
|
||||||
|
}
|
||||||
|
|
||||||
if($return_tags)
|
if ($return_tags) {
|
||||||
$res->tags = $this->getTags();
|
$res->tags = $this->getTags();
|
||||||
|
}
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete(bool $softly = true, bool $all_copies = false): void
|
public function delete(bool $softly = true, bool $all_copies = false): void
|
||||||
{
|
{
|
||||||
if($all_copies) {
|
if ($all_copies) {
|
||||||
$ctx = DatabaseConnection::i()->getContext();
|
$ctx = DatabaseConnection::i()->getContext();
|
||||||
$ctx->table("documents")->where("copy_of", $this->getId())->delete();
|
$ctx->table("documents")->where("copy_of", $this->getId())->delete();
|
||||||
}
|
}
|
||||||
parent::delete($softly);
|
parent::delete($softly);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function detectTypeByFormat(string $format)
|
public static function detectTypeByFormat(string $format)
|
||||||
{
|
{
|
||||||
switch(mb_strtolower($format)) {
|
switch (mb_strtolower($format)) {
|
||||||
case "txt": case "docx": case "doc": case "odt": case "pptx": case "ppt": case "xlsx": case "xls": case "md":
|
case "txt": case "docx": case "doc": case "odt": case "pptx": case "ppt": case "xlsx": case "xls": case "md":
|
||||||
return 1;
|
return 1;
|
||||||
case "zip": case "rar": case "7z":
|
case "zip": case "rar": case "7z":
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Models\Repositories\Users;
|
use openvk\Web\Models\Repositories\Users;
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
|
@ -8,7 +12,7 @@ class EmailChangeVerification extends PasswordReset
|
||||||
{
|
{
|
||||||
protected $tableName = "email_change_verifications";
|
protected $tableName = "email_change_verifications";
|
||||||
|
|
||||||
function getNewEmail(): string
|
public function getNewEmail(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->new_email;
|
return $this->getRecord()->new_email;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
namespace openvk\Web\Models\Entities;
|
|
||||||
use openvk\Web\Models\Repositories\Users;
|
declare(strict_types=1);
|
||||||
use openvk\Web\Models\RowModel;
|
|
||||||
use openvk\Web\Util\DateTime;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
class EmailVerification extends PasswordReset
|
use openvk\Web\Models\Repositories\Users;
|
||||||
{
|
use openvk\Web\Models\RowModel;
|
||||||
protected $tableName = "email_verifications";
|
use openvk\Web\Util\DateTime;
|
||||||
}
|
|
||||||
|
class EmailVerification extends PasswordReset
|
||||||
|
{
|
||||||
|
protected $tableName = "email_verifications";
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
|
@ -7,53 +11,54 @@ use Nette\Utils\{Image, ImageException};
|
||||||
|
|
||||||
class Gift extends RowModel
|
class Gift extends RowModel
|
||||||
{
|
{
|
||||||
const IMAGE_MAXSIZE = 131072;
|
public const IMAGE_MAXSIZE = 131072;
|
||||||
const IMAGE_BINARY = 0;
|
public const IMAGE_BINARY = 0;
|
||||||
const IMAGE_BASE64 = 1;
|
public const IMAGE_BASE64 = 1;
|
||||||
const IMAGE_URL = 2;
|
public const IMAGE_URL = 2;
|
||||||
|
|
||||||
const PERIOD_IGNORE = 0;
|
public const PERIOD_IGNORE = 0;
|
||||||
const PERIOD_SET = 1;
|
public const PERIOD_SET = 1;
|
||||||
const PERIOD_SET_IF_NONE = 2;
|
public const PERIOD_SET_IF_NONE = 2;
|
||||||
|
|
||||||
protected $tableName = "gifts";
|
protected $tableName = "gifts";
|
||||||
|
|
||||||
function getName(): string
|
public function getName(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->internal_name;
|
return $this->getRecord()->internal_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPrice(): int
|
public function getPrice(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->price;
|
return $this->getRecord()->price;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUsages(): int
|
public function getUsages(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->usages;
|
return $this->getRecord()->usages;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUsagesBy(User $user, ?int $since = NULL): int
|
public function getUsagesBy(User $user, ?int $since = null): int
|
||||||
{
|
{
|
||||||
$sent = $this->getRecord()
|
$sent = $this->getRecord()
|
||||||
->related("gift_user_relations.gift")
|
->related("gift_user_relations.gift")
|
||||||
->where("sender", $user->getId())
|
->where("sender", $user->getId())
|
||||||
->where("sent >= ?", $since ?? $this->getRecord()->limit_period ?? 0);
|
->where("sent >= ?", $since ?? $this->getRecord()->limit_period ?? 0);
|
||||||
|
|
||||||
return sizeof($sent);
|
return sizeof($sent);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUsagesLeft(User $user): float
|
public function getUsagesLeft(User $user): float
|
||||||
{
|
{
|
||||||
if($this->getLimit() === INF)
|
if ($this->getLimit() === INF) {
|
||||||
return INF;
|
return INF;
|
||||||
|
}
|
||||||
|
|
||||||
return max(0, $this->getLimit() - $this->getUsagesBy($user));
|
return max(0, $this->getLimit() - $this->getUsagesBy($user));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getImage(int $type = 0): /* ?binary */ string
|
public function getImage(int $type = 0): /* ?binary */ string
|
||||||
{
|
{
|
||||||
switch($type) {
|
switch ($type) {
|
||||||
default:
|
default:
|
||||||
case static::IMAGE_BINARY:
|
case static::IMAGE_BINARY:
|
||||||
return $this->getRecord()->image ?? "";
|
return $this->getRecord()->image ?? "";
|
||||||
|
@ -66,99 +71,100 @@ class Gift extends RowModel
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLimit(): float
|
public function getLimit(): float
|
||||||
{
|
{
|
||||||
$limit = $this->getRecord()->limit;
|
$limit = $this->getRecord()->limit;
|
||||||
|
|
||||||
return !$limit ? INF : (float) $limit;
|
return !$limit ? INF : (float) $limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLimitResetTime(): ?DateTime
|
public function getLimitResetTime(): ?DateTime
|
||||||
{
|
{
|
||||||
return is_null($t = $this->getRecord()->limit_period) ? NULL : new DateTime($t);
|
return is_null($t = $this->getRecord()->limit_period) ? null : new DateTime($t);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUpdateDate(): DateTime
|
public function getUpdateDate(): DateTime
|
||||||
{
|
{
|
||||||
return new DateTime($this->getRecord()->updated);
|
return new DateTime($this->getRecord()->updated);
|
||||||
}
|
}
|
||||||
|
|
||||||
function canUse(User $user): bool
|
public function canUse(User $user): bool
|
||||||
{
|
{
|
||||||
return $this->getUsagesLeft($user) > 0;
|
return $this->getUsagesLeft($user) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isFree(): bool
|
public function isFree(): bool
|
||||||
{
|
{
|
||||||
return $this->getPrice() === 0;
|
return $this->getPrice() === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function used(): void
|
public function used(): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("usages", $this->getUsages() + 1);
|
$this->stateChanges("usages", $this->getUsages() + 1);
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setName(string $name): void
|
public function setName(string $name): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("internal_name", $name);
|
$this->stateChanges("internal_name", $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setImage(string $file): bool
|
public function setImage(string $file): bool
|
||||||
{
|
{
|
||||||
$imgBlob;
|
$imgBlob;
|
||||||
try {
|
try {
|
||||||
$image = Image::fromFile($file);
|
$image = Image::fromFile($file);
|
||||||
$image->resize(512, 512, Image::SHRINK_ONLY);
|
$image->resize(512, 512, Image::SHRINK_ONLY);
|
||||||
|
|
||||||
$imgBlob = $image->toString(Image::PNG);
|
$imgBlob = $image->toString(Image::PNG);
|
||||||
} catch(ImageException $ex) {
|
} catch (ImageException $ex) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(strlen($imgBlob) > (2**24 - 1)) {
|
if (strlen($imgBlob) > (2 ** 24 - 1)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
$this->stateChanges("updated", time());
|
$this->stateChanges("updated", time());
|
||||||
$this->stateChanges("image", $imgBlob);
|
$this->stateChanges("image", $imgBlob);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLimit(?float $limit = NULL, int $periodBehaviour = 0): void
|
public function setLimit(?float $limit = null, int $periodBehaviour = 0): void
|
||||||
{
|
{
|
||||||
$limit ??= $this->getLimit();
|
$limit ??= $this->getLimit();
|
||||||
$limit = $limit === INF ? NULL : (int) $limit;
|
$limit = $limit === INF ? null : (int) $limit;
|
||||||
$this->stateChanges("limit", $limit);
|
$this->stateChanges("limit", $limit);
|
||||||
|
|
||||||
if(!$limit) {
|
if (!$limit) {
|
||||||
$this->stateChanges("limit_period", NULL);
|
$this->stateChanges("limit_period", null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch($periodBehaviour) {
|
switch ($periodBehaviour) {
|
||||||
default:
|
default:
|
||||||
case static::PERIOD_IGNORE:
|
case static::PERIOD_IGNORE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case static::PERIOD_SET:
|
case static::PERIOD_SET:
|
||||||
$this->stateChanges("limit_period", time());
|
$this->stateChanges("limit_period", time());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case static::PERIOD_SET_IF_NONE:
|
case static::PERIOD_SET_IF_NONE:
|
||||||
if(is_null($this->getRecord()) || is_null($this->getRecord()->limit_period))
|
if (is_null($this->getRecord()) || is_null($this->getRecord()->limit_period)) {
|
||||||
$this->stateChanges("limit_period", time());
|
$this->stateChanges("limit_period", time());
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete(bool $softly = true): void
|
public function delete(bool $softly = true): void
|
||||||
{
|
{
|
||||||
$this->getRecord()->related("gift_relations.gift")->delete();
|
$this->getRecord()->related("gift_relations.gift")->delete();
|
||||||
|
|
||||||
parent::delete($softly);
|
parent::delete($softly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use Chandler\Database\DatabaseConnection as DB;
|
use Chandler\Database\DatabaseConnection as DB;
|
||||||
use openvk\Web\Models\Repositories\Gifts;
|
use openvk\Web\Models\Repositories\Gifts;
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
|
@ -8,19 +12,20 @@ use Transliterator;
|
||||||
class GiftCategory extends RowModel
|
class GiftCategory extends RowModel
|
||||||
{
|
{
|
||||||
protected $tableName = "gift_categories";
|
protected $tableName = "gift_categories";
|
||||||
|
|
||||||
private function getLocalization(string $language): object
|
private function getLocalization(string $language): object
|
||||||
{
|
{
|
||||||
return $this->getRecord()
|
return $this->getRecord()
|
||||||
->related("gift_categories_locales.category")
|
->related("gift_categories_locales.category")
|
||||||
->where("language", $language);
|
->where("language", $language);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createLocalizationIfNotExists(string $language): void
|
private function createLocalizationIfNotExists(string $language): void
|
||||||
{
|
{
|
||||||
if(!is_null($this->getLocalization($language)->fetch()))
|
if (!is_null($this->getLocalization($language)->fetch())) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DB::i()->getContext()->table("gift_categories_locales")->insert([
|
DB::i()->getContext()->table("gift_categories_locales")->insert([
|
||||||
"category" => $this->getId(),
|
"category" => $this->getId(),
|
||||||
"language" => $language,
|
"language" => $language,
|
||||||
|
@ -28,8 +33,8 @@ class GiftCategory extends RowModel
|
||||||
"description" => "Sample Text",
|
"description" => "Sample Text",
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSlug(): string
|
public function getSlug(): string
|
||||||
{
|
{
|
||||||
return str_replace("ʹ", "-", Transliterator::createFromRules(
|
return str_replace("ʹ", "-", Transliterator::createFromRules(
|
||||||
":: Any-Latin;"
|
":: Any-Latin;"
|
||||||
|
@ -41,116 +46,123 @@ class GiftCategory extends RowModel
|
||||||
. "[:Separator:] > '-'"
|
. "[:Separator:] > '-'"
|
||||||
)->transliterate($this->getName()));
|
)->transliterate($this->getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getThumbnailURL(): string
|
public function getThumbnailURL(): string
|
||||||
{
|
{
|
||||||
$primeGift = iterator_to_array($this->getGifts(1, 1))[0];
|
$primeGift = iterator_to_array($this->getGifts(1, 1))[0];
|
||||||
$serverUrl = ovk_scheme(true) . $_SERVER["SERVER_NAME"];
|
$serverUrl = ovk_scheme(true) . $_SERVER["SERVER_NAME"];
|
||||||
if(!$primeGift)
|
if (!$primeGift) {
|
||||||
return "$serverUrl/assets/packages/static/openvk/img/camera_200.png";
|
return "$serverUrl/assets/packages/static/openvk/img/camera_200.png";
|
||||||
|
}
|
||||||
|
|
||||||
return $primeGift->getImage(Gift::IMAGE_URL);
|
return $primeGift->getImage(Gift::IMAGE_URL);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getName(string $language = "_", bool $returnNull = false): ?string
|
public function getName(string $language = "_", bool $returnNull = false): ?string
|
||||||
{
|
{
|
||||||
$loc = $this->getLocalization($language)->fetch();
|
$loc = $this->getLocalization($language)->fetch();
|
||||||
if(!$loc) {
|
if (!$loc) {
|
||||||
if($returnNull)
|
if ($returnNull) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return $language === "_" ? "Unlocalized" : $this->getName();
|
return $language === "_" ? "Unlocalized" : $this->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $loc->name;
|
return $loc->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDescription(string $language = "_", bool $returnNull = false): ?string
|
public function getDescription(string $language = "_", bool $returnNull = false): ?string
|
||||||
{
|
{
|
||||||
$loc = $this->getLocalization($language)->fetch();
|
$loc = $this->getLocalization($language)->fetch();
|
||||||
if(!$loc) {
|
if (!$loc) {
|
||||||
if($returnNull)
|
if ($returnNull) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return $language === "_" ? "Unlocalized" : $this->getDescription();
|
return $language === "_" ? "Unlocalized" : $this->getDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $loc->description;
|
return $loc->description;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGifts(int $page = -1, ?int $perPage = NULL, &$count = nullptr): \Traversable
|
public function getGifts(int $page = -1, ?int $perPage = null, &$count = nullptr): \Traversable
|
||||||
{
|
{
|
||||||
$gifts = $this->getRecord()->related("gift_relations.category");
|
$gifts = $this->getRecord()->related("gift_relations.category");
|
||||||
if($page !== -1) {
|
if ($page !== -1) {
|
||||||
$count = $gifts->count();
|
$count = $gifts->count();
|
||||||
$gifts = $gifts->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE);
|
$gifts = $gifts->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($gifts as $rel)
|
foreach ($gifts as $rel) {
|
||||||
yield (new Gifts)->get($rel->gift);
|
yield (new Gifts())->get($rel->gift);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isMagical(): bool
|
public function isMagical(): bool
|
||||||
{
|
{
|
||||||
return !is_null($this->getRecord()->autoquery);
|
return !is_null($this->getRecord()->autoquery);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasGift(Gift $gift): bool
|
public function hasGift(Gift $gift): bool
|
||||||
{
|
{
|
||||||
$rels = $this->getRecord()->related("gift_relations.category");
|
$rels = $this->getRecord()->related("gift_relations.category");
|
||||||
|
|
||||||
return $rels->where("gift", $gift->getId())->count() > 0;
|
return $rels->where("gift", $gift->getId())->count() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addGift(Gift $gift): void
|
public function addGift(Gift $gift): void
|
||||||
{
|
{
|
||||||
if($this->hasGift($gift))
|
if ($this->hasGift($gift)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DB::i()->getContext()->table("gift_relations")->insert([
|
DB::i()->getContext()->table("gift_relations")->insert([
|
||||||
"category" => $this->getId(),
|
"category" => $this->getId(),
|
||||||
"gift" => $gift->getId(),
|
"gift" => $gift->getId(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeGift(Gift $gift): void
|
public function removeGift(Gift $gift): void
|
||||||
{
|
{
|
||||||
if(!$this->hasGift($gift))
|
if (!$this->hasGift($gift)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DB::i()->getContext()->table("gift_relations")->where([
|
DB::i()->getContext()->table("gift_relations")->where([
|
||||||
"category" => $this->getId(),
|
"category" => $this->getId(),
|
||||||
"gift" => $gift->getId(),
|
"gift" => $gift->getId(),
|
||||||
])->delete();
|
])->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setName(string $language, string $name): void
|
public function setName(string $language, string $name): void
|
||||||
{
|
{
|
||||||
$this->createLocalizationIfNotExists($language);
|
$this->createLocalizationIfNotExists($language);
|
||||||
$this->getLocalization($language)->update([
|
$this->getLocalization($language)->update([
|
||||||
"name" => $name,
|
"name" => $name,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDescription(string $language, string $description): void
|
public function setDescription(string $language, string $description): void
|
||||||
{
|
{
|
||||||
$this->createLocalizationIfNotExists($language);
|
$this->createLocalizationIfNotExists($language);
|
||||||
$this->getLocalization($language)->update([
|
$this->getLocalization($language)->update([
|
||||||
"description" => $description,
|
"description" => $description,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAutoQuery(?array $query = NULL): void
|
public function setAutoQuery(?array $query = null): void
|
||||||
{
|
{
|
||||||
if(is_null($query)) {
|
if (is_null($query)) {
|
||||||
$this->stateChanges("autoquery", NULL);
|
$this->stateChanges("autoquery", null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$allowedColumns = ["price", "usages"];
|
$allowedColumns = ["price", "usages"];
|
||||||
if(array_diff_key($query, array_flip($allowedColumns)))
|
if (array_diff_key($query, array_flip($allowedColumns))) {
|
||||||
throw new \LogicException("Invalid query");
|
throw new \LogicException("Invalid query");
|
||||||
|
}
|
||||||
|
|
||||||
$this->stateChanges("autoquery", serialize($query));
|
$this->stateChanges("autoquery", serialize($query));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +1,49 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
|
|
||||||
class IP extends RowModel
|
class IP extends RowModel
|
||||||
{
|
{
|
||||||
protected $tableName = "ip";
|
protected $tableName = "ip";
|
||||||
|
|
||||||
const RL_RESET = 0;
|
public const RL_RESET = 0;
|
||||||
const RL_CANEXEC = 1;
|
public const RL_CANEXEC = 1;
|
||||||
const RL_VIOLATION = 2;
|
public const RL_VIOLATION = 2;
|
||||||
const RL_BANNED = 3;
|
public const RL_BANNED = 3;
|
||||||
|
|
||||||
function getIp(): string
|
public function getIp(): string
|
||||||
{
|
{
|
||||||
return inet_ntop($this->getRecord()->ip);
|
return inet_ntop($this->getRecord()->ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDiscoveryDate(): DateTime
|
public function getDiscoveryDate(): DateTime
|
||||||
{
|
{
|
||||||
return new DateTime($this->getRecord()->first_seen);
|
return new DateTime($this->getRecord()->first_seen);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isBanned(): bool
|
public function isBanned(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->banned;
|
return (bool) $this->getRecord()->banned;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ban(): void
|
public function ban(): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("banned", true);
|
$this->stateChanges("banned", true);
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
function pardon(): void
|
public function pardon(): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("banned", false);
|
$this->stateChanges("banned", false);
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
function clear(): void
|
public function clear(): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("rate_limit_counter_start", 0);
|
$this->stateChanges("rate_limit_counter_start", 0);
|
||||||
$this->stateChanges("rate_limit_counter", 0);
|
$this->stateChanges("rate_limit_counter", 0);
|
||||||
|
@ -47,45 +51,45 @@ class IP extends RowModel
|
||||||
$this->stateChanges("rate_limit_violation_counter", 0);
|
$this->stateChanges("rate_limit_violation_counter", 0);
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
function rateLimit(int $actionComplexity = 1): int
|
public function rateLimit(int $actionComplexity = 1): int
|
||||||
{
|
{
|
||||||
$counterSessionStart = $this->getRecord()->rate_limit_counter_start;
|
$counterSessionStart = $this->getRecord()->rate_limit_counter_start;
|
||||||
$vCounterSessionStart = $this->getRecord()->rate_limit_violation_counter_start;
|
$vCounterSessionStart = $this->getRecord()->rate_limit_violation_counter_start;
|
||||||
|
|
||||||
$aCounter = $this->getRecord()->rate_limit_counter;
|
$aCounter = $this->getRecord()->rate_limit_counter;
|
||||||
$vCounter = $this->getRecord()->rate_limit_violation_counter;
|
$vCounter = $this->getRecord()->rate_limit_violation_counter;
|
||||||
|
|
||||||
$config = (object) OPENVK_ROOT_CONF["openvk"]["preferences"]["security"]["rateLimits"];
|
$config = (object) OPENVK_ROOT_CONF["openvk"]["preferences"]["security"]["rateLimits"];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if((time() - $config->time) > $counterSessionStart) {
|
if ((time() - $config->time) > $counterSessionStart) {
|
||||||
$counterSessionStart = time();
|
$counterSessionStart = time();
|
||||||
$aCounter = $actionComplexity;
|
$aCounter = $actionComplexity;
|
||||||
|
|
||||||
return static::RL_RESET;
|
return static::RL_RESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(($aCounter + $actionComplexity) <= $config->actions) {
|
if (($aCounter + $actionComplexity) <= $config->actions) {
|
||||||
$aCounter += $actionComplexity;
|
$aCounter += $actionComplexity;
|
||||||
|
|
||||||
return static::RL_CANEXEC;
|
return static::RL_CANEXEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((time() - $config->maxViolationsAge) > $vCounterSessionStart) {
|
if ((time() - $config->maxViolationsAge) > $vCounterSessionStart) {
|
||||||
$vCounterSessionStart = time();
|
$vCounterSessionStart = time();
|
||||||
$vCounter = 1;
|
$vCounter = 1;
|
||||||
|
|
||||||
return static::RL_VIOLATION;
|
return static::RL_VIOLATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
$vCounter += 1;
|
$vCounter += 1;
|
||||||
if($vCounter >= $config->maxViolations) {
|
if ($vCounter >= $config->maxViolations) {
|
||||||
$this->stateChanges("banned", true);
|
$this->stateChanges("banned", true);
|
||||||
|
|
||||||
return static::RL_BANNED;
|
return static::RL_BANNED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return static::RL_VIOLATION;
|
return static::RL_VIOLATION;
|
||||||
} finally {
|
} finally {
|
||||||
$this->stateChanges("rate_limit_counter_start", $counterSessionStart);
|
$this->stateChanges("rate_limit_counter_start", $counterSessionStart);
|
||||||
|
@ -95,21 +99,23 @@ class IP extends RowModel
|
||||||
$this->save(false);
|
$this->save(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setIp(string $ip): void
|
public function setIp(string $ip): void
|
||||||
{
|
{
|
||||||
$ip = inet_pton($ip);
|
$ip = inet_pton($ip);
|
||||||
if(!$ip)
|
if (!$ip) {
|
||||||
throw new \UnexpectedValueException("Malformed IP address");
|
throw new \UnexpectedValueException("Malformed IP address");
|
||||||
|
}
|
||||||
|
|
||||||
$this->stateChanges("ip", $ip);
|
$this->stateChanges("ip", $ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
function save(?bool $log = false): void
|
public function save(?bool $log = false): void
|
||||||
{
|
{
|
||||||
if(is_null($this->getRecord()))
|
if (is_null($this->getRecord())) {
|
||||||
$this->stateChanges("first_seen", time());
|
$this->stateChanges("first_seen", time());
|
||||||
|
}
|
||||||
|
|
||||||
parent::save($log);
|
parent::save($log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Models\Entities\{Photo, Message, Correspondence};
|
use openvk\Web\Models\Entities\{Photo, Message, Correspondence};
|
||||||
|
@ -10,47 +14,46 @@ use Chandler\Security\User as ChandlerUser;
|
||||||
|
|
||||||
class Manager extends RowModel
|
class Manager extends RowModel
|
||||||
{
|
{
|
||||||
|
use Traits\TSubscribable;
|
||||||
protected $tableName = "group_coadmins";
|
protected $tableName = "group_coadmins";
|
||||||
|
|
||||||
function getId(): int
|
public function getId(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->id;
|
return $this->getRecord()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUserId(): int
|
public function getUserId(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->user;
|
return $this->getRecord()->user;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUser(): ?User
|
public function getUser(): ?User
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getRecord()->user);
|
return (new Users())->get($this->getRecord()->user);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getClubId(): int
|
public function getClubId(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->club;
|
return $this->getRecord()->club;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getClub(): ?Club
|
public function getClub(): ?Club
|
||||||
{
|
{
|
||||||
return (new Clubs)->get($this->getRecord()->club);
|
return (new Clubs())->get($this->getRecord()->club);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComment(): string
|
public function getComment(): string
|
||||||
{
|
{
|
||||||
return is_null($this->getRecord()->comment) ? "" : $this->getRecord()->comment;
|
return is_null($this->getRecord()->comment) ? "" : $this->getRecord()->comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isHidden(): bool
|
public function isHidden(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->hidden;
|
return (bool) $this->getRecord()->hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isClubPinned(): bool
|
public function isClubPinned(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->club_pinned;
|
return (bool) $this->getRecord()->club_pinned;
|
||||||
}
|
}
|
||||||
|
|
||||||
use Traits\TSubscribable;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,68 +1,77 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use Nette\InvalidStateException as ISE;
|
use Nette\InvalidStateException as ISE;
|
||||||
|
|
||||||
abstract class Media extends Postable
|
abstract class Media extends Postable
|
||||||
{
|
{
|
||||||
protected $fileExtension = "oct"; #octet stream xddd
|
protected $fileExtension = "oct"; #octet stream xddd
|
||||||
protected $upperNodeReferenceColumnName = "owner";
|
protected $upperNodeReferenceColumnName = "owner";
|
||||||
protected $processingPlaceholder = NULL;
|
protected $processingPlaceholder = null;
|
||||||
protected $processingTime = 30;
|
protected $processingTime = 30;
|
||||||
|
|
||||||
function __destruct()
|
public function __destruct()
|
||||||
{
|
{
|
||||||
#Remove data, if model wasn't presisted
|
#Remove data, if model wasn't presisted
|
||||||
if(isset($this->changes["hash"]))
|
if (isset($this->changes["hash"])) {
|
||||||
unlink($this->pathFromHash($this->changes["hash"]));
|
unlink($this->pathFromHash($this->changes["hash"]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getBaseDir(): string
|
protected function getBaseDir(): string
|
||||||
{
|
{
|
||||||
$uploadSettings = OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"];
|
$uploadSettings = OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"];
|
||||||
if($uploadSettings["mode"] === "server" && $uploadSettings["server"]["kind"] === "cdn")
|
if ($uploadSettings["mode"] === "server" && $uploadSettings["server"]["kind"] === "cdn") {
|
||||||
return $uploadSettings["server"]["directory"];
|
return $uploadSettings["server"]["directory"];
|
||||||
else
|
} else {
|
||||||
return OPENVK_ROOT . "/storage/";
|
return OPENVK_ROOT . "/storage/";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function checkIfFileIsProcessed(): bool
|
protected function checkIfFileIsProcessed(): bool
|
||||||
{
|
{
|
||||||
throw new \LogicException("checkIfFileIsProcessed is not implemented");
|
throw new \LogicException("checkIfFileIsProcessed is not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract protected function saveFile(string $filename, string $hash): bool;
|
abstract protected function saveFile(string $filename, string $hash): bool;
|
||||||
|
|
||||||
protected function pathFromHash(string $hash): string
|
protected function pathFromHash(string $hash): string
|
||||||
{
|
{
|
||||||
$dir = $this->getBaseDir() . substr($hash, 0, 2);
|
$dir = $this->getBaseDir() . substr($hash, 0, 2);
|
||||||
if(!is_dir($dir))
|
if (!is_dir($dir)) {
|
||||||
mkdir($dir);
|
mkdir($dir);
|
||||||
|
}
|
||||||
|
|
||||||
return "$dir/$hash." . $this->fileExtension;
|
return "$dir/$hash." . $this->fileExtension;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFileName(): string
|
public function getFileName(): string
|
||||||
{
|
{
|
||||||
return $this->pathFromHash($this->getRecord()->hash);
|
return $this->pathFromHash($this->getRecord()->hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getURL(): string
|
public function getURL(): string
|
||||||
{
|
{
|
||||||
if(!is_null($this->processingPlaceholder))
|
if (!is_null($this->processingPlaceholder)) {
|
||||||
if(!$this->isProcessed())
|
if (!$this->isProcessed()) {
|
||||||
return "/assets/packages/static/openvk/$this->processingPlaceholder.$this->fileExtension";
|
return "/assets/packages/static/openvk/$this->processingPlaceholder.$this->fileExtension";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$hash = $this->getRecord()->hash;
|
$hash = $this->getRecord()->hash;
|
||||||
|
|
||||||
switch(OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["mode"]) {
|
switch (OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["mode"]) {
|
||||||
default:
|
default:
|
||||||
case "default":
|
case "default":
|
||||||
case "basic":
|
case "basic":
|
||||||
return "http://" . $_SERVER['HTTP_HOST'] . "/blob_" . substr($hash, 0, 2) . "/$hash.$this->fileExtension";
|
return "http://" . $_SERVER['HTTP_HOST'] . "/blob_" . substr($hash, 0, 2) . "/$hash.$this->fileExtension";
|
||||||
break;
|
break;
|
||||||
case "accelerated":
|
case "accelerated":
|
||||||
return "http://" . $_SERVER['HTTP_HOST'] . "/openvk-datastore/$hash.$this->fileExtension";
|
return "http://" . $_SERVER['HTTP_HOST'] . "/openvk-datastore/$hash.$this->fileExtension";
|
||||||
break;
|
break;
|
||||||
case "server":
|
case "server":
|
||||||
$settings = (object) OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["server"];
|
$settings = (object) OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["server"];
|
||||||
return (
|
return (
|
||||||
|
@ -71,26 +80,29 @@ abstract class Media extends Postable
|
||||||
$settings->path .
|
$settings->path .
|
||||||
substr($hash, 0, 2) . "/$hash.$this->fileExtension"
|
substr($hash, 0, 2) . "/$hash.$this->fileExtension"
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDescription(): ?string
|
public function getDescription(): ?string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->description;
|
return $this->getRecord()->description;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function isProcessed(): bool
|
protected function isProcessed(): bool
|
||||||
{
|
{
|
||||||
if(is_null($this->processingPlaceholder))
|
if (is_null($this->processingPlaceholder)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if($this->getRecord()->processed)
|
if ($this->getRecord()->processed) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
$timeDiff = time() - $this->getRecord()->last_checked;
|
$timeDiff = time() - $this->getRecord()->last_checked;
|
||||||
if($timeDiff < $this->processingTime)
|
if ($timeDiff < $this->processingTime) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$res = $this->checkIfFileIsProcessed();
|
$res = $this->checkIfFileIsProcessed();
|
||||||
$this->stateChanges("last_checked", time());
|
$this->stateChanges("last_checked", time());
|
||||||
|
@ -99,31 +111,32 @@ abstract class Media extends Postable
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDeleted(): bool
|
public function isDeleted(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->deleted;
|
return (bool) $this->getRecord()->deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setHash(string $hash): void
|
public function setHash(string $hash): void
|
||||||
{
|
{
|
||||||
throw new ISE("Setting file hash manually is forbidden");
|
throw new ISE("Setting file hash manually is forbidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
function setFile(array $file): void
|
public function setFile(array $file): void
|
||||||
{
|
{
|
||||||
if($file["error"] !== UPLOAD_ERR_OK)
|
if ($file["error"] !== UPLOAD_ERR_OK) {
|
||||||
throw new ISE("File uploaded is corrupted");
|
throw new ISE("File uploaded is corrupted");
|
||||||
|
}
|
||||||
|
|
||||||
$hash = hash_file("whirlpool", $file["tmp_name"]);
|
$hash = hash_file("whirlpool", $file["tmp_name"]);
|
||||||
$this->saveFile($file["tmp_name"], $hash);
|
$this->saveFile($file["tmp_name"], $hash);
|
||||||
|
|
||||||
$this->stateChanges("hash", $hash);
|
$this->stateChanges("hash", $hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
function save(?bool $log = false): void
|
public function save(?bool $log = false): void
|
||||||
{
|
{
|
||||||
if(!is_null($this->processingPlaceholder) && is_null($this->getRecord())) {
|
if (!is_null($this->processingPlaceholder) && is_null($this->getRecord())) {
|
||||||
$this->stateChanges("processed", 0);
|
$this->stateChanges("processed", 0);
|
||||||
$this->stateChanges("last_checked", time());
|
$this->stateChanges("last_checked", time());
|
||||||
}
|
}
|
||||||
|
@ -131,20 +144,22 @@ abstract class Media extends Postable
|
||||||
parent::save($log);
|
parent::save($log);
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete(bool $softly = true): void
|
public function delete(bool $softly = true): void
|
||||||
{
|
{
|
||||||
$deleteQuirk = ovkGetQuirk("blobs.erase-upon-deletion");
|
$deleteQuirk = ovkGetQuirk("blobs.erase-upon-deletion");
|
||||||
if($deleteQuirk === 2 || ($deleteQuirk === 1 && !$softly))
|
if ($deleteQuirk === 2 || ($deleteQuirk === 1 && !$softly)) {
|
||||||
@unlink($this->getFileName());
|
@unlink($this->getFileName());
|
||||||
|
}
|
||||||
|
|
||||||
parent::delete($softly);
|
parent::delete($softly);
|
||||||
}
|
}
|
||||||
|
|
||||||
function undelete(): void
|
public function undelete(): void
|
||||||
{
|
{
|
||||||
if(ovkGetQuirk("blobs.erase-upon-deletion") === 2)
|
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)");
|
throw new \LogicException("Can't undelete model which is tied to blob, because of config constraint (quriks.yml:blobs.erase-upon-deletion)");
|
||||||
|
}
|
||||||
|
|
||||||
parent::undelete();
|
parent::undelete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use Nette\Database\Table\ActiveRow;
|
use Nette\Database\Table\ActiveRow;
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
|
@ -10,196 +14,212 @@ use Chandler\Database\DatabaseConnection;
|
||||||
|
|
||||||
abstract class MediaCollection extends RowModel
|
abstract class MediaCollection extends RowModel
|
||||||
{
|
{
|
||||||
|
use Traits\TOwnable;
|
||||||
protected $relTableName;
|
protected $relTableName;
|
||||||
protected $entityTableName;
|
protected $entityTableName;
|
||||||
protected $entityClassName;
|
protected $entityClassName;
|
||||||
protected $allowDuplicates = true;
|
protected $allowDuplicates = true;
|
||||||
|
|
||||||
protected $specialNames = [];
|
protected $specialNames = [];
|
||||||
|
|
||||||
protected $relations;
|
protected $relations;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum amount of items Collection can have
|
* Maximum amount of items Collection can have
|
||||||
*/
|
*/
|
||||||
const MAX_ITEMS = INF;
|
public const MAX_ITEMS = INF;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum amount of Collections with same "owner" allowed
|
* Maximum amount of Collections with same "owner" allowed
|
||||||
*/
|
*/
|
||||||
const MAX_COUNT = INF;
|
public const MAX_COUNT = INF;
|
||||||
|
|
||||||
function __construct(?ActiveRow $ar = NULL)
|
public function __construct(?ActiveRow $ar = null)
|
||||||
{
|
{
|
||||||
parent::__construct($ar);
|
parent::__construct($ar);
|
||||||
|
|
||||||
$this->relations = DatabaseConnection::i()->getContext()->table($this->relTableName);
|
$this->relations = DatabaseConnection::i()->getContext()->table($this->relTableName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function entitySuitable(RowModel $entity): bool
|
private function entitySuitable(RowModel $entity): bool
|
||||||
{
|
{
|
||||||
if(($class = get_class($entity)) !== $this->entityClassName)
|
if (($class = get_class($entity)) !== $this->entityClassName) {
|
||||||
throw new \UnexpectedValueException("This MediaCollection can only store '$this->entityClassName' (not '$class').");
|
throw new \UnexpectedValueException("This MediaCollection can only store '$this->entityClassName' (not '$class').");
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOwner(): RowModel
|
public function getOwner(): RowModel
|
||||||
{
|
{
|
||||||
$oid = $this->getRecord()->owner;
|
$oid = $this->getRecord()->owner;
|
||||||
if($oid > 0)
|
if ($oid > 0) {
|
||||||
return (new Users)->get($oid);
|
return (new Users())->get($oid);
|
||||||
else
|
} else {
|
||||||
return (new Clubs)->get($oid * -1);
|
return (new Clubs())->get($oid * -1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPrettyId(): string
|
public function getPrettyId(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->owner . "_" . $this->getRecord()->id;
|
return $this->getRecord()->owner . "_" . $this->getRecord()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getName(): string
|
public function getName(): string
|
||||||
{
|
{
|
||||||
$special = $this->getRecord()->special_type;
|
$special = $this->getRecord()->special_type;
|
||||||
if($special === 0)
|
if ($special === 0) {
|
||||||
return $this->getRecord()->name;
|
return $this->getRecord()->name;
|
||||||
|
}
|
||||||
|
|
||||||
$sName = $this->specialNames[$special];
|
$sName = $this->specialNames[$special];
|
||||||
if(!$sName)
|
if (!$sName) {
|
||||||
return $this->getRecord()->name;
|
return $this->getRecord()->name;
|
||||||
|
}
|
||||||
if($sName[0] === "_")
|
|
||||||
|
if ($sName[0] === "_") {
|
||||||
$sName = tr(substr($sName, 1));
|
$sName = tr(substr($sName, 1));
|
||||||
|
}
|
||||||
|
|
||||||
return $sName;
|
return $sName;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDescription(): ?string
|
public function getDescription(): ?string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->description;
|
return $this->getRecord()->description;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract function getCoverURL(): ?string;
|
|
||||||
|
|
||||||
function fetchClassic(int $offset = 0, ?int $limit = NULL): \Traversable
|
abstract public function getCoverURL(): ?string;
|
||||||
|
|
||||||
|
public function fetchClassic(int $offset = 0, ?int $limit = null): \Traversable
|
||||||
{
|
{
|
||||||
$related = $this->getRecord()->related("$this->relTableName.collection")
|
$related = $this->getRecord()->related("$this->relTableName.collection")
|
||||||
->limit($limit ?? OPENVK_DEFAULT_PER_PAGE, $offset)
|
->limit($limit ?? OPENVK_DEFAULT_PER_PAGE, $offset)
|
||||||
->order("media ASC");
|
->order("media ASC");
|
||||||
|
|
||||||
foreach($related as $rel) {
|
foreach ($related as $rel) {
|
||||||
$media = $rel->ref($this->entityTableName, "media");
|
$media = $rel->ref($this->entityTableName, "media");
|
||||||
if(!$media)
|
if (!$media) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
yield new $this->entityClassName($media);
|
yield new $this->entityClassName($media);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetch(int $page = 1, ?int $perPage = NULL): \Traversable
|
public function fetch(int $page = 1, ?int $perPage = null): \Traversable
|
||||||
{
|
{
|
||||||
$page = max(1, $page);
|
$page = max(1, $page);
|
||||||
$perPage ??= OPENVK_DEFAULT_PER_PAGE;
|
$perPage ??= OPENVK_DEFAULT_PER_PAGE;
|
||||||
|
|
||||||
return $this->fetchClassic($perPage * ($page - 1), $perPage);
|
return $this->fetchClassic($perPage * ($page - 1), $perPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
function size(): int
|
public function size(): int
|
||||||
{
|
{
|
||||||
return sizeof($this->getRecord()->related("$this->relTableName.collection"));
|
return sizeof($this->getRecord()->related("$this->relTableName.collection"));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCreationTime(): DateTime
|
public function getCreationTime(): DateTime
|
||||||
{
|
{
|
||||||
return new DateTime($this->getRecord()->created);
|
return new DateTime($this->getRecord()->created);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPublicationTime(): DateTime
|
public function getPublicationTime(): DateTime
|
||||||
{
|
{
|
||||||
return $this->getCreationTime();
|
return $this->getCreationTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEditTime(): ?DateTime
|
public function getEditTime(): ?DateTime
|
||||||
{
|
{
|
||||||
$edited = $this->getRecord()->edited;
|
$edited = $this->getRecord()->edited;
|
||||||
if(is_null($edited)) return NULL;
|
if (is_null($edited)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return new DateTime($edited);
|
return new DateTime($edited);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isCreatedBySystem(): bool
|
public function isCreatedBySystem(): bool
|
||||||
{
|
{
|
||||||
return $this->getRecord()->special_type !== 0;
|
return $this->getRecord()->special_type !== 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function add(RowModel $entity): bool
|
public function add(RowModel $entity): bool
|
||||||
{
|
{
|
||||||
$this->entitySuitable($entity);
|
$this->entitySuitable($entity);
|
||||||
|
|
||||||
if(!$this->allowDuplicates)
|
|
||||||
if($this->has($entity))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(self::MAX_ITEMS != INF)
|
if (!$this->allowDuplicates) {
|
||||||
if(sizeof($this->relations->where("collection", $this->getId())) > self::MAX_ITEMS)
|
if ($this->has($entity)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self::MAX_ITEMS != INF) {
|
||||||
|
if (sizeof($this->relations->where("collection", $this->getId())) > self::MAX_ITEMS) {
|
||||||
throw new \OutOfBoundsException("Collection is full");
|
throw new \OutOfBoundsException("Collection is full");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->relations->insert([
|
$this->relations->insert([
|
||||||
"collection" => $this->getId(),
|
"collection" => $this->getId(),
|
||||||
"media" => $entity->getId(),
|
"media" => $entity->getId(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function remove(RowModel $entity): bool
|
public function remove(RowModel $entity): bool
|
||||||
{
|
{
|
||||||
$this->entitySuitable($entity);
|
$this->entitySuitable($entity);
|
||||||
|
|
||||||
return $this->relations->where([
|
return $this->relations->where([
|
||||||
"collection" => $this->getId(),
|
"collection" => $this->getId(),
|
||||||
"media" => $entity->getId(),
|
"media" => $entity->getId(),
|
||||||
])->delete() > 0;
|
])->delete() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function has(RowModel $entity): bool
|
public function has(RowModel $entity): bool
|
||||||
{
|
{
|
||||||
$this->entitySuitable($entity);
|
$this->entitySuitable($entity);
|
||||||
|
|
||||||
$rel = $this->relations->where([
|
$rel = $this->relations->where([
|
||||||
"collection" => $this->getId(),
|
"collection" => $this->getId(),
|
||||||
"media" => $entity->getId(),
|
"media" => $entity->getId(),
|
||||||
])->fetch();
|
])->fetch();
|
||||||
|
|
||||||
return !is_null($rel);
|
return !is_null($rel);
|
||||||
}
|
}
|
||||||
|
|
||||||
function save(?bool $log = false): void
|
public function save(?bool $log = false): void
|
||||||
{
|
{
|
||||||
$thisTable = DatabaseConnection::i()->getContext()->table($this->tableName);
|
$thisTable = DatabaseConnection::i()->getContext()->table($this->tableName);
|
||||||
if(self::MAX_COUNT != INF)
|
if (self::MAX_COUNT != INF) {
|
||||||
if(isset($this->changes["owner"]))
|
if (isset($this->changes["owner"])) {
|
||||||
if(sizeof($thisTable->where("owner", $this->changes["owner"])) > self::MAX_COUNT)
|
if (sizeof($thisTable->where("owner", $this->changes["owner"])) > self::MAX_COUNT) {
|
||||||
throw new \OutOfBoundsException("Maximum amount of collections");
|
throw new \OutOfBoundsException("Maximum amount of collections");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(is_null($this->getRecord()))
|
if (is_null($this->getRecord())) {
|
||||||
if(!isset($this->changes["created"]))
|
if (!isset($this->changes["created"])) {
|
||||||
$this->stateChanges("created", time());
|
$this->stateChanges("created", time());
|
||||||
else
|
} else {
|
||||||
$this->stateChanges("edited", time());
|
$this->stateChanges("edited", time());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
parent::save($log);
|
parent::save($log);
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete(bool $softly = true): void
|
public function delete(bool $softly = true): void
|
||||||
{
|
{
|
||||||
if(!$softly) {
|
if (!$softly) {
|
||||||
$this->relations->where("collection", $this->getId())
|
$this->relations->where("collection", $this->getId())
|
||||||
->delete();
|
->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::delete($softly);
|
parent::delete($softly);
|
||||||
}
|
}
|
||||||
|
|
||||||
use Traits\TOwnable;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use Chandler\Database\DatabaseConnection;
|
use Chandler\Database\DatabaseConnection;
|
||||||
use openvk\Web\Models\Repositories\Clubs;
|
use openvk\Web\Models\Repositories\Clubs;
|
||||||
use openvk\Web\Models\Repositories\Users;
|
use openvk\Web\Models\Repositories\Users;
|
||||||
|
@ -12,108 +16,114 @@ use openvk\Web\Util\DateTime;
|
||||||
*/
|
*/
|
||||||
class Message extends RowModel
|
class Message extends RowModel
|
||||||
{
|
{
|
||||||
|
use Traits\TRichText;
|
||||||
|
use Traits\TAttachmentHost;
|
||||||
protected $tableName = "messages";
|
protected $tableName = "messages";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get origin of the message.
|
* Get origin of the message.
|
||||||
*
|
*
|
||||||
* Returns either user or club.
|
* Returns either user or club.
|
||||||
*
|
*
|
||||||
* @returns User|Club
|
* @returns User|Club
|
||||||
*/
|
*/
|
||||||
function getSender(): ?RowModel
|
public function getSender(): ?RowModel
|
||||||
{
|
{
|
||||||
if($this->getRecord()->sender_type === 'openvk\Web\Models\Entities\User')
|
if ($this->getRecord()->sender_type === 'openvk\Web\Models\Entities\User') {
|
||||||
return (new Users)->get($this->getRecord()->sender_id);
|
return (new Users())->get($this->getRecord()->sender_id);
|
||||||
else if($this->getRecord()->sender_type === 'openvk\Web\Models\Entities\Club')
|
} elseif ($this->getRecord()->sender_type === 'openvk\Web\Models\Entities\Club') {
|
||||||
return (new Clubs)->get($this->getRecord()->sender_id);
|
return (new Clubs())->get($this->getRecord()->sender_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the destination of the message.
|
* Get the destination of the message.
|
||||||
*
|
*
|
||||||
* Returns either user or club.
|
* Returns either user or club.
|
||||||
*
|
*
|
||||||
* @returns User|Club
|
* @returns User|Club
|
||||||
*/
|
*/
|
||||||
function getRecipient(): ?RowModel
|
public function getRecipient(): ?RowModel
|
||||||
{
|
{
|
||||||
if($this->getRecord()->recipient_type === 'openvk\Web\Models\Entities\User')
|
if ($this->getRecord()->recipient_type === 'openvk\Web\Models\Entities\User') {
|
||||||
return (new Users)->get($this->getRecord()->recipient_id);
|
return (new Users())->get($this->getRecord()->recipient_id);
|
||||||
else if($this->getRecord()->recipient_type === 'openvk\Web\Models\Entities\Club')
|
} elseif ($this->getRecord()->recipient_type === 'openvk\Web\Models\Entities\Club') {
|
||||||
return (new Clubs)->get($this->getRecord()->recipient_id);
|
return (new Clubs())->get($this->getRecord()->recipient_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUnreadState(): int
|
public function getUnreadState(): int
|
||||||
{
|
{
|
||||||
trigger_error("TODO: use isUnread", E_USER_DEPRECATED);
|
trigger_error("TODO: use isUnread", E_USER_DEPRECATED);
|
||||||
|
|
||||||
return (int) $this->isUnread();
|
return (int) $this->isUnread();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get date of initial publication.
|
* Get date of initial publication.
|
||||||
*
|
*
|
||||||
* @returns DateTime
|
* @returns DateTime
|
||||||
*/
|
*/
|
||||||
function getSendTime(): DateTime
|
public function getSendTime(): DateTime
|
||||||
{
|
{
|
||||||
return new DateTime($this->getRecord()->created);
|
return new DateTime($this->getRecord()->created);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSendTimeHumanized(): string
|
public function getSendTimeHumanized(): string
|
||||||
{
|
{
|
||||||
$dateTime = new DateTime($this->getRecord()->created);
|
$dateTime = new DateTime($this->getRecord()->created);
|
||||||
|
|
||||||
if($dateTime->format("%d.%m.%y") == ovk_strftime_safe("%d.%m.%y", time())) {
|
if ($dateTime->format("%d.%m.%y") == ovk_strftime_safe("%d.%m.%y", time())) {
|
||||||
return $dateTime->format("%T");
|
return $dateTime->format("%T");
|
||||||
} else {
|
} else {
|
||||||
return $dateTime->format("%d.%m.%y");
|
return $dateTime->format("%d.%m.%y");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get date of last edit, if any edits were made, otherwise null.
|
* Get date of last edit, if any edits were made, otherwise null.
|
||||||
*
|
*
|
||||||
* @returns DateTime|null
|
* @returns DateTime|null
|
||||||
*/
|
*/
|
||||||
function getEditTime(): ?DateTime
|
public function getEditTime(): ?DateTime
|
||||||
{
|
{
|
||||||
$edited = $this->getRecord()->edited;
|
$edited = $this->getRecord()->edited;
|
||||||
if(is_null($edited)) return NULL;
|
if (is_null($edited)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return new DateTime($edited);
|
return new DateTime($edited);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this message an ad?
|
* Is this message an ad?
|
||||||
*
|
*
|
||||||
* Messages can never be ads.
|
* Messages can never be ads.
|
||||||
*
|
*
|
||||||
* @returns false
|
* @returns false
|
||||||
*/
|
*/
|
||||||
function isAd(): bool
|
public function isAd(): bool
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isUnread(): bool
|
public function isUnread(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->unread;
|
return (bool) $this->getRecord()->unread;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplify to array
|
* Simplify to array
|
||||||
*
|
*
|
||||||
* @returns array
|
* @returns array
|
||||||
*/
|
*/
|
||||||
function simplify(): array
|
public function simplify(): array
|
||||||
{
|
{
|
||||||
$author = $this->getSender();
|
$author = $this->getSender();
|
||||||
|
|
||||||
$attachments = [];
|
$attachments = [];
|
||||||
foreach($this->getChildren() as $attachment) {
|
foreach ($this->getChildren() as $attachment) {
|
||||||
if($attachment instanceof Photo) {
|
if ($attachment instanceof Photo) {
|
||||||
$attachments[] = [
|
$attachments[] = [
|
||||||
"type" => "photo",
|
"type" => "photo",
|
||||||
"link" => "/photo" . $attachment->getPrettyId(),
|
"link" => "/photo" . $attachment->getPrettyId(),
|
||||||
|
@ -124,31 +134,28 @@ class Message extends RowModel
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
$attachments[] = [
|
$attachments[] = [
|
||||||
"type" => "unknown"
|
"type" => "unknown",
|
||||||
];
|
];
|
||||||
|
|
||||||
# throw new \Exception("Unknown attachment type: " . get_class($attachment));
|
# throw new \Exception("Unknown attachment type: " . get_class($attachment));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
"uuid" => $this->getId(),
|
"uuid" => $this->getId(),
|
||||||
"sender" => [
|
"sender" => [
|
||||||
"id" => $author->getId(),
|
"id" => $author->getId(),
|
||||||
"link" => $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $author->getURL(),
|
"link" => $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $author->getURL(),
|
||||||
"avatar" => $author->getAvatarUrl(),
|
"avatar" => $author->getAvatarUrl(),
|
||||||
"name" => $author->getFirstName().$unreadmsg,
|
"name" => $author->getFirstName() . $unreadmsg,
|
||||||
],
|
],
|
||||||
"timing" => [
|
"timing" => [
|
||||||
"sent" => (string) $this->getSendTimeHumanized(),
|
"sent" => (string) $this->getSendTimeHumanized(),
|
||||||
"edited" => is_null($this->getEditTime()) ? NULL : (string) $this->getEditTime(),
|
"edited" => is_null($this->getEditTime()) ? null : (string) $this->getEditTime(),
|
||||||
],
|
],
|
||||||
"text" => $this->getText(),
|
"text" => $this->getText(),
|
||||||
"read" => !$this->isUnread(),
|
"read" => !$this->isUnread(),
|
||||||
"attachments" => $attachments,
|
"attachments" => $attachments,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
use Traits\TRichText;
|
|
||||||
use Traits\TAttachmentHost;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
use openvk\Web\Models\Repositories\{Users};
|
use openvk\Web\Models\Repositories\{Users};
|
||||||
|
@ -9,52 +13,52 @@ class NoSpamLog extends RowModel
|
||||||
{
|
{
|
||||||
protected $tableName = "noSpam_templates";
|
protected $tableName = "noSpam_templates";
|
||||||
|
|
||||||
function getId(): int
|
public function getId(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->id;
|
return $this->getRecord()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUser(): ?User
|
public function getUser(): ?User
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getRecord()->user);
|
return (new Users())->get($this->getRecord()->user);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getModel(): string
|
public function getModel(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->model;
|
return $this->getRecord()->model;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRegex(): ?string
|
public function getRegex(): ?string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->regex;
|
return $this->getRecord()->regex;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRequest(): ?string
|
public function getRequest(): ?string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->request;
|
return $this->getRecord()->request;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCount(): int
|
public function getCount(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->count;
|
return $this->getRecord()->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTime(): DateTime
|
public function getTime(): DateTime
|
||||||
{
|
{
|
||||||
return new DateTime($this->getRecord()->time);
|
return new DateTime($this->getRecord()->time);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getItems(): ?array
|
public function getItems(): ?array
|
||||||
{
|
{
|
||||||
return explode(",", $this->getRecord()->items);
|
return explode(",", $this->getRecord()->items);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTypeRaw(): int
|
public function getTypeRaw(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->ban_type;
|
return $this->getRecord()->ban_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getType(): string
|
public function getType(): string
|
||||||
{
|
{
|
||||||
switch ($this->getTypeRaw()) {
|
switch ($this->getTypeRaw()) {
|
||||||
case 1: return "О";
|
case 1: return "О";
|
||||||
|
@ -64,7 +68,7 @@ class NoSpamLog extends RowModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isRollbacked(): bool
|
public function isRollbacked(): bool
|
||||||
{
|
{
|
||||||
return !is_null($this->getRecord()->rollback);
|
return !is_null($this->getRecord()->rollback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use HTMLPurifier_Config;
|
use HTMLPurifier_Config;
|
||||||
use HTMLPurifier;
|
use HTMLPurifier;
|
||||||
|
|
||||||
class Note extends Postable
|
class Note extends Postable
|
||||||
{
|
{
|
||||||
protected $tableName = "notes";
|
protected $tableName = "notes";
|
||||||
|
|
||||||
protected function renderHTML(): string
|
protected function renderHTML(): string
|
||||||
{
|
{
|
||||||
$config = HTMLPurifier_Config::createDefault();
|
$config = HTMLPurifier_Config::createDefault();
|
||||||
|
@ -74,61 +78,63 @@ class Note extends Postable
|
||||||
$config->set("Attr.AllowedClasses", [
|
$config->set("Attr.AllowedClasses", [
|
||||||
"underline",
|
"underline",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$source = NULL;
|
$source = null;
|
||||||
if(is_null($this->getRecord())) {
|
if (is_null($this->getRecord())) {
|
||||||
if(isset($this->changes["source"]))
|
if (isset($this->changes["source"])) {
|
||||||
$source = $this->changes["source"];
|
$source = $this->changes["source"];
|
||||||
else
|
} else {
|
||||||
throw new \LogicException("Can't render note without content set.");
|
throw new \LogicException("Can't render note without content set.");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$source = $this->getRecord()->source;
|
$source = $this->getRecord()->source;
|
||||||
}
|
}
|
||||||
|
|
||||||
$purifier = new HTMLPurifier($config);
|
$purifier = new HTMLPurifier($config);
|
||||||
return $purifier->purify($source);
|
return $purifier->purify($source);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getName(): string
|
public function getName(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->name;
|
return $this->getRecord()->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPreview(int $length = 25): string
|
public function getPreview(int $length = 25): string
|
||||||
{
|
{
|
||||||
return ovk_proc_strtr(strip_tags($this->getRecord()->source), $length);
|
return ovk_proc_strtr(strip_tags($this->getRecord()->source), $length);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getText(): string
|
public function getText(): string
|
||||||
{
|
{
|
||||||
if(is_null($this->getRecord()))
|
if (is_null($this->getRecord())) {
|
||||||
return $this->renderHTML();
|
return $this->renderHTML();
|
||||||
|
}
|
||||||
|
|
||||||
$cached = $this->getRecord()->cached_content;
|
$cached = $this->getRecord()->cached_content;
|
||||||
if(!$cached) {
|
if (!$cached) {
|
||||||
$cached = $this->renderHTML();
|
$cached = $this->renderHTML();
|
||||||
$this->setCached_Content($cached);
|
$this->setCached_Content($cached);
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $cached;
|
return $cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSource(): string
|
public function getSource(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->source;
|
return $this->getRecord()->source;
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBeViewedBy(?User $user = NULL): bool
|
public function canBeViewedBy(?User $user = null): bool
|
||||||
{
|
{
|
||||||
if($this->isDeleted() || $this->getOwner()->isDeleted()) {
|
if ($this->isDeleted() || $this->getOwner()->isDeleted()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->getOwner()->getPrivacyPermission('notes.read', $user) && $this->getOwner()->canBeViewedBy($user);
|
return $this->getOwner()->getPrivacyPermission('notes.read', $user) && $this->getOwner()->canBeViewedBy($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toVkApiStruct(): object
|
public function toVkApiStruct(): object
|
||||||
{
|
{
|
||||||
$res = (object) [];
|
$res = (object) [];
|
||||||
|
|
||||||
|
@ -140,7 +146,7 @@ class Note extends Postable
|
||||||
$res->date = $this->getPublicationTime()->timestamp();
|
$res->date = $this->getPublicationTime()->timestamp();
|
||||||
$res->comments = $this->getCommentsCount();
|
$res->comments = $this->getCommentsCount();
|
||||||
$res->read_comments = $this->getCommentsCount();
|
$res->read_comments = $this->getCommentsCount();
|
||||||
$res->view_url = "/note".$this->getOwner()->getId()."_".$this->getVirtualId();
|
$res->view_url = "/note" . $this->getOwner()->getId() . "_" . $this->getVirtualId();
|
||||||
$res->privacy_view = 1;
|
$res->privacy_view = 1;
|
||||||
$res->can_comment = 1;
|
$res->can_comment = 1;
|
||||||
$res->text_wiki = "r";
|
$res->text_wiki = "r";
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Notifications;
|
namespace openvk\Web\Models\Entities\Notifications;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\{User, Club};
|
use openvk\Web\Models\Entities\{User, Club};
|
||||||
|
|
||||||
final class ClubModeratorNotification extends Notification
|
final class ClubModeratorNotification extends Notification
|
||||||
{
|
{
|
||||||
protected $actionCode = 5;
|
protected $actionCode = 5;
|
||||||
|
|
||||||
function __construct(User $recipient, Club $group, User $admin)
|
public function __construct(User $recipient, Club $group, User $admin)
|
||||||
{
|
{
|
||||||
parent::__construct($recipient, $group, $admin, time(), "");
|
parent::__construct($recipient, $group, $admin, time(), "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Notifications;
|
namespace openvk\Web\Models\Entities\Notifications;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
|
|
||||||
final class CoinsTransferNotification extends Notification
|
final class CoinsTransferNotification extends Notification
|
||||||
{
|
{
|
||||||
protected $actionCode = 9602;
|
protected $actionCode = 9602;
|
||||||
|
|
||||||
function __construct(User $receiver, User $sender, int $value, string $message)
|
public function __construct(User $receiver, User $sender, int $value, string $message)
|
||||||
{
|
{
|
||||||
parent::__construct($receiver, $receiver, $sender, time(), $value . " " . $message);
|
parent::__construct($receiver, $receiver, $sender, time(), $value . " " . $message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Notifications;
|
namespace openvk\Web\Models\Entities\Notifications;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\{User, Post, Comment};
|
use openvk\Web\Models\Entities\{User, Post, Comment};
|
||||||
|
|
||||||
final class CommentNotification extends Notification
|
final class CommentNotification extends Notification
|
||||||
{
|
{
|
||||||
protected $actionCode = 2;
|
protected $actionCode = 2;
|
||||||
|
|
||||||
function __construct(User $recipient, Comment $comment, $postable, User $commenter)
|
public function __construct(User $recipient, Comment $comment, $postable, User $commenter)
|
||||||
{
|
{
|
||||||
parent::__construct($recipient, $postable, $commenter, time(), ovk_proc_strtr(strip_tags($comment->getText()), 400));
|
parent::__construct($recipient, $postable, $commenter, time(), ovk_proc_strtr(strip_tags($comment->getText()), 400));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Notifications;
|
namespace openvk\Web\Models\Entities\Notifications;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
|
|
||||||
final class FriendRemovalNotification extends Notification
|
final class FriendRemovalNotification extends Notification
|
||||||
{
|
{
|
||||||
protected $actionCode = 4;
|
protected $actionCode = 4;
|
||||||
|
|
||||||
function __construct(User $recipient, User $friend, User $remover)
|
public function __construct(User $recipient, User $friend, User $remover)
|
||||||
{
|
{
|
||||||
parent::__construct($recipient, $friend, $remover, time(), "");
|
parent::__construct($recipient, $friend, $remover, time(), "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Notifications;
|
namespace openvk\Web\Models\Entities\Notifications;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\{User, Gift};
|
use openvk\Web\Models\Entities\{User, Gift};
|
||||||
|
|
||||||
final class GiftNotification extends Notification
|
final class GiftNotification extends Notification
|
||||||
{
|
{
|
||||||
protected $actionCode = 9601;
|
protected $actionCode = 9601;
|
||||||
|
|
||||||
function __construct(User $receiver, User $sender, Gift $gift, ?string $comment)
|
public function __construct(User $receiver, User $sender, Gift $gift, ?string $comment)
|
||||||
{
|
{
|
||||||
parent::__construct($receiver, $gift, $sender, time(), $comment ?? "");
|
parent::__construct($receiver, $gift, $sender, time(), $comment ?? "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Notifications;
|
namespace openvk\Web\Models\Entities\Notifications;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\{User, Post};
|
use openvk\Web\Models\Entities\{User, Post};
|
||||||
|
|
||||||
final class LikeNotification extends Notification
|
final class LikeNotification extends Notification
|
||||||
{
|
{
|
||||||
protected $actionCode = 0;
|
protected $actionCode = 0;
|
||||||
protected $threshold = 120;
|
protected $threshold = 120;
|
||||||
|
|
||||||
function __construct(User $recipient, Post $post, User $liker)
|
public function __construct(User $recipient, Post $post, User $liker)
|
||||||
{
|
{
|
||||||
parent::__construct($recipient, $post, $liker, time(), "");
|
parent::__construct($recipient, $post, $liker, time(), "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Notifications;
|
namespace openvk\Web\Models\Entities\Notifications;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\Postable;
|
use openvk\Web\Models\Entities\Postable;
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
|
|
||||||
final class MentionNotification extends Notification
|
final class MentionNotification extends Notification
|
||||||
{
|
{
|
||||||
protected $actionCode = 4;
|
protected $actionCode = 4;
|
||||||
|
|
||||||
function __construct(User $recipient, Postable $discussionHost, $mentioner, string $quote = "")
|
public function __construct(User $recipient, Postable $discussionHost, $mentioner, string $quote = "")
|
||||||
{
|
{
|
||||||
parent::__construct($recipient, $mentioner, $discussionHost, time(), $quote);
|
parent::__construct($recipient, $mentioner, $discussionHost, time(), $quote);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Notifications;
|
namespace openvk\Web\Models\Entities\Notifications;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\{User, Club};
|
use openvk\Web\Models\Entities\{User, Club};
|
||||||
|
|
||||||
final class NewSuggestedPostsNotification extends Notification
|
final class NewSuggestedPostsNotification extends Notification
|
||||||
{
|
{
|
||||||
protected $actionCode = 7;
|
protected $actionCode = 7;
|
||||||
|
|
||||||
function __construct(User $owner, Club $group)
|
public function __construct(User $owner, Club $group)
|
||||||
{
|
{
|
||||||
parent::__construct($owner, $owner, $group, time(), "");
|
parent::__construct($owner, $owner, $group, time(), "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Notifications;
|
namespace openvk\Web\Models\Entities\Notifications;
|
||||||
|
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Models\Entities\{User};
|
use openvk\Web\Models\Entities\{User};
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
|
@ -12,11 +16,11 @@ class Notification
|
||||||
private $targetModel;
|
private $targetModel;
|
||||||
private $time;
|
private $time;
|
||||||
private $data;
|
private $data;
|
||||||
|
|
||||||
protected $actionCode = NULL;
|
protected $actionCode = null;
|
||||||
protected $threshold = -1;
|
protected $threshold = -1;
|
||||||
|
|
||||||
function __construct(User $recipient, $originModel, $targetModel, ?int $time = NULL, string $data = "")
|
public function __construct(User $recipient, $originModel, $targetModel, ?int $time = null, string $data = "")
|
||||||
{
|
{
|
||||||
$this->recipient = $recipient;
|
$this->recipient = $recipient;
|
||||||
$this->originModel = $originModel;
|
$this->originModel = $originModel;
|
||||||
|
@ -24,67 +28,68 @@ class Notification
|
||||||
$this->time = $time ?? time();
|
$this->time = $time ?? time();
|
||||||
$this->data = $data;
|
$this->data = $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function encodeType(object $model): int
|
private function encodeType(object $model): int
|
||||||
{
|
{
|
||||||
return (int) json_decode(file_get_contents(__DIR__ . "/../../../../data/modelCodes.json"), true)[get_class($model)];
|
return (int) json_decode(file_get_contents(__DIR__ . "/../../../../data/modelCodes.json"), true)[get_class($model)];
|
||||||
}
|
}
|
||||||
|
|
||||||
function reverseModelOrder(): bool
|
public function reverseModelOrder(): bool
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getActionCode(): int
|
public function getActionCode(): int
|
||||||
{
|
{
|
||||||
return $this->actionCode;
|
return $this->actionCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setActionCode(int $code): void
|
public function setActionCode(int $code): void
|
||||||
{
|
{
|
||||||
$this->actionCode = $this->actionCode ?? $code;
|
$this->actionCode ??= $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTemplatePath(): string
|
public function getTemplatePath(): string
|
||||||
{
|
{
|
||||||
return implode("_", [
|
return implode("_", [
|
||||||
"./../components/notifications/$this->actionCode/",
|
"./../components/notifications/$this->actionCode/",
|
||||||
$this->encodeType($this->originModel),
|
$this->encodeType($this->originModel),
|
||||||
$this->encodeType($this->targetModel),
|
$this->encodeType($this->targetModel),
|
||||||
".xml"
|
".xml",
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRecipient(): User
|
public function getRecipient(): User
|
||||||
{
|
{
|
||||||
return $this->recipient;
|
return $this->recipient;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getModel(int $index): RowModel
|
public function getModel(int $index): RowModel
|
||||||
{
|
{
|
||||||
switch($index) {
|
switch ($index) {
|
||||||
case 0:
|
case 0:
|
||||||
return $this->originModel;
|
return $this->originModel;
|
||||||
case 1:
|
case 1:
|
||||||
return $this->targetModel;
|
return $this->targetModel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getData(): string
|
public function getData(): string
|
||||||
{
|
{
|
||||||
return $this->data;
|
return $this->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDateTime(): DateTime
|
public function getDateTime(): DateTime
|
||||||
{
|
{
|
||||||
return new DateTime($this->time);
|
return new DateTime($this->time);
|
||||||
}
|
}
|
||||||
|
|
||||||
function emit(): bool
|
public function emit(): bool
|
||||||
{
|
{
|
||||||
if(!($e = eventdb()))
|
if (!($e = eventdb())) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
"recipient" => $this->recipient->getId(),
|
"recipient" => $this->recipient->getId(),
|
||||||
"originModelType" => $this->encodeType($this->originModel),
|
"originModelType" => $this->encodeType($this->originModel),
|
||||||
|
@ -95,56 +100,57 @@ class Notification
|
||||||
"additionalPayload" => $this->data,
|
"additionalPayload" => $this->data,
|
||||||
"timestamp" => $this->time,
|
"timestamp" => $this->time,
|
||||||
];
|
];
|
||||||
|
|
||||||
$edb = $e->getConnection();
|
$edb = $e->getConnection();
|
||||||
if($this->threshold !== -1) {
|
if ($this->threshold !== -1) {
|
||||||
# Event is thersholded, check if there is similar event
|
# Event is thersholded, check if there is similar event
|
||||||
$query = <<<'QUERY'
|
$query = <<<'QUERY'
|
||||||
SELECT * FROM `notifications` WHERE `recipientType`=0 AND `recipientId`=? AND `originModelType`=? AND `originModelId`=? AND `targetModelType`=? AND `targetModelId`=? AND `modelAction`=? AND `additionalData`=? AND `timestamp` > (? - ?)
|
SELECT * FROM `notifications` WHERE `recipientType`=0 AND `recipientId`=? AND `originModelType`=? AND `originModelId`=? AND `targetModelType`=? AND `targetModelId`=? AND `modelAction`=? AND `additionalData`=? AND `timestamp` > (? - ?)
|
||||||
QUERY;
|
QUERY;
|
||||||
$result = $edb->query($query, ...array_merge(array_values($data), [ $this->threshold ]));
|
$result = $edb->query($query, ...array_merge(array_values($data), [ $this->threshold ]));
|
||||||
if($result->getRowCount() > 0)
|
if ($result->getRowCount() > 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$edb->query("INSERT INTO notifications VALUES (0, ?, ?, ?, ?, ?, ?, ?, ?)", ...array_values($data));
|
$edb->query("INSERT INTO notifications VALUES (0, ?, ?, ?, ?, ?, ?, ?, ?)", ...array_values($data));
|
||||||
|
|
||||||
$kafkaConf = OPENVK_ROOT_CONF["openvk"]["credentials"]["notificationsBroker"];
|
$kafkaConf = OPENVK_ROOT_CONF["openvk"]["credentials"]["notificationsBroker"];
|
||||||
if($kafkaConf["enable"]) {
|
if ($kafkaConf["enable"]) {
|
||||||
$kafkaConf = $kafkaConf["kafka"];
|
$kafkaConf = $kafkaConf["kafka"];
|
||||||
$brokerConf = new Conf();
|
$brokerConf = new Conf();
|
||||||
$brokerConf->set("log_level", (string) LOG_DEBUG);
|
$brokerConf->set("log_level", (string) LOG_DEBUG);
|
||||||
$brokerConf->set("debug", "all");
|
$brokerConf->set("debug", "all");
|
||||||
|
|
||||||
$producer = new Producer($brokerConf);
|
$producer = new Producer($brokerConf);
|
||||||
$producer->addBrokers($kafkaConf["addr"] . ":" . $kafkaConf["port"]);
|
$producer->addBrokers($kafkaConf["addr"] . ":" . $kafkaConf["port"]);
|
||||||
|
|
||||||
$descriptor = implode(",", [
|
$descriptor = implode(",", [
|
||||||
str_replace("\\", ".", get_class($this)),
|
str_replace("\\", ".", get_class($this)),
|
||||||
$this->recipient->getId(),
|
$this->recipient->getId(),
|
||||||
base64_encode(serialize((object) $data)),
|
base64_encode(serialize((object) $data)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$notifTopic = $producer->newTopic($kafkaConf["topic"]);
|
$notifTopic = $producer->newTopic($kafkaConf["topic"]);
|
||||||
$notifTopic->produce(RD_KAFKA_PARTITION_UA, RD_KAFKA_MSG_F_BLOCK, $descriptor);
|
$notifTopic->produce(RD_KAFKA_PARTITION_UA, RD_KAFKA_MSG_F_BLOCK, $descriptor);
|
||||||
$producer->flush(100);
|
$producer->flush(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVkApiInfo()
|
public function getVkApiInfo()
|
||||||
{
|
{
|
||||||
$origin_m = $this->encodeType($this->originModel);
|
$origin_m = $this->encodeType($this->originModel);
|
||||||
$target_m = $this->encodeType($this->targetModel);
|
$target_m = $this->encodeType($this->targetModel);
|
||||||
|
|
||||||
$info = [
|
$info = [
|
||||||
"type" => "",
|
"type" => "",
|
||||||
"parent" => NULL,
|
"parent" => null,
|
||||||
"feedback" => NULL,
|
"feedback" => null,
|
||||||
];
|
];
|
||||||
|
|
||||||
switch($this->getActionCode()) {
|
switch ($this->getActionCode()) {
|
||||||
case 0:
|
case 0:
|
||||||
$info["type"] = "like_post";
|
$info["type"] = "like_post";
|
||||||
$info["parent"] = $this->getModel(0)->toNotifApiStruct();
|
$info["parent"] = $this->getModel(0)->toNotifApiStruct();
|
||||||
|
@ -153,32 +159,32 @@ QUERY;
|
||||||
case 1:
|
case 1:
|
||||||
$info["type"] = "copy_post";
|
$info["type"] = "copy_post";
|
||||||
$info["parent"] = $this->getModel(0)->toNotifApiStruct();
|
$info["parent"] = $this->getModel(0)->toNotifApiStruct();
|
||||||
$info["feedback"] = NULL; # todo
|
$info["feedback"] = null; # todo
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
switch($origin_m) {
|
switch ($origin_m) {
|
||||||
case 19:
|
case 19:
|
||||||
$info["type"] = "comment_video";
|
$info["type"] = "comment_video";
|
||||||
$info["parent"] = $this->getModel(0)->toNotifApiStruct();
|
$info["parent"] = $this->getModel(0)->toNotifApiStruct();
|
||||||
$info["feedback"] = NULL; # айди коммента не сохраняется в бд( ну пиздец блять
|
$info["feedback"] = null; # айди коммента не сохраняется в бд( ну пиздец блять
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
$info["type"] = "comment_photo";
|
$info["type"] = "comment_photo";
|
||||||
$info["parent"] = $this->getModel(0)->toNotifApiStruct();
|
$info["parent"] = $this->getModel(0)->toNotifApiStruct();
|
||||||
$info["feedback"] = NULL;
|
$info["feedback"] = null;
|
||||||
break;
|
break;
|
||||||
# unstandart (vk forgor about notes)
|
# unstandart (vk forgor about notes)
|
||||||
case 10:
|
case 10:
|
||||||
$info["type"] = "comment_note";
|
$info["type"] = "comment_note";
|
||||||
$info["parent"] = $this->getModel(0)->toVkApiStruct();
|
$info["parent"] = $this->getModel(0)->toVkApiStruct();
|
||||||
$info["feedback"] = NULL;
|
$info["feedback"] = null;
|
||||||
break;
|
break;
|
||||||
case 14:
|
case 14:
|
||||||
$info["type"] = "comment_post";
|
$info["type"] = "comment_post";
|
||||||
$info["parent"] = $this->getModel(0)->toNotifApiStruct();
|
$info["parent"] = $this->getModel(0)->toNotifApiStruct();
|
||||||
$info["feedback"] = NULL;
|
$info["feedback"] = null;
|
||||||
break;
|
break;
|
||||||
# unused (users don't have topics bruh)
|
# unused (users don't have topics bruh)
|
||||||
case 21:
|
case 21:
|
||||||
$info["type"] = "comment_topic";
|
$info["type"] = "comment_topic";
|
||||||
$info["parent"] = $this->getModel(0)->toVkApiStruct(0, 90);
|
$info["parent"] = $this->getModel(0)->toVkApiStruct(0, 90);
|
||||||
|
@ -194,7 +200,7 @@ QUERY;
|
||||||
$info["feedback"] = $this->getModel(0)->toNotifApiStruct();
|
$info["feedback"] = $this->getModel(0)->toNotifApiStruct();
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
switch($target_m) {
|
switch ($target_m) {
|
||||||
case 14:
|
case 14:
|
||||||
$info["type"] = "mention";
|
$info["type"] = "mention";
|
||||||
$info["feedback"] = $this->getModel(1)->toNotifApiStruct();
|
$info["feedback"] = $this->getModel(1)->toNotifApiStruct();
|
||||||
|
@ -207,7 +213,7 @@ QUERY;
|
||||||
$info["type"] = "mention_comment_photo";
|
$info["type"] = "mention_comment_photo";
|
||||||
$info["parent"] = $this->getModel(1)->toNotifApiStruct();
|
$info["parent"] = $this->getModel(1)->toNotifApiStruct();
|
||||||
break;
|
break;
|
||||||
# unstandart
|
# unstandart
|
||||||
case 10:
|
case 10:
|
||||||
$info["type"] = "mention_comment_note";
|
$info["type"] = "mention_comment_note";
|
||||||
$info["parent"] = $this->getModel(1)->toVkApiStruct();
|
$info["parent"] = $this->getModel(1)->toVkApiStruct();
|
||||||
|
@ -224,15 +230,15 @@ QUERY;
|
||||||
$info["type"] = "make_you_admin";
|
$info["type"] = "make_you_admin";
|
||||||
$info["parent"] = $this->getModel(0)->toVkApiStruct($this->getModel(1));
|
$info["parent"] = $this->getModel(0)->toVkApiStruct($this->getModel(1));
|
||||||
break;
|
break;
|
||||||
# Нужно доделать после мержа #935
|
# Нужно доделать после мержа #935
|
||||||
case 6:
|
case 6:
|
||||||
$info["type"] = "wall_publish";
|
$info["type"] = "wall_publish";
|
||||||
break;
|
break;
|
||||||
# В вк не было такого уведомления, так что unstandart
|
# В вк не было такого уведомления, так что unstandart
|
||||||
case 7:
|
case 7:
|
||||||
$info["type"] = "new_posts_in_club";
|
$info["type"] = "new_posts_in_club";
|
||||||
break;
|
break;
|
||||||
# В вк при передаче подарков приходит сообщение, а не уведомление, так что unstandart
|
# В вк при передаче подарков приходит сообщение, а не уведомление, так что unstandart
|
||||||
case 9601:
|
case 9601:
|
||||||
$info["type"] = "sent_gift";
|
$info["type"] = "sent_gift";
|
||||||
$info["parent"] = $this->getModel(1)->toVkApiStruct($this->getModel(1));
|
$info["parent"] = $this->getModel(1)->toVkApiStruct($this->getModel(1));
|
||||||
|
@ -247,23 +253,23 @@ QUERY;
|
||||||
$info["parent"]->count = $this->getData();
|
$info["parent"]->count = $this->getData();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$info["type"] = NULL;
|
$info["type"] = null;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $info;
|
return $info;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toVkApiStruct()
|
public function toVkApiStruct()
|
||||||
{
|
{
|
||||||
$res = (object)[];
|
$res = (object) [];
|
||||||
|
|
||||||
$info = $this->getVkApiInfo();
|
$info = $this->getVkApiInfo();
|
||||||
$res->type = $info["type"];
|
$res->type = $info["type"];
|
||||||
$res->date = $this->getDateTime()->timestamp();
|
$res->date = $this->getDateTime()->timestamp();
|
||||||
$res->parent = $info["parent"];
|
$res->parent = $info["parent"];
|
||||||
$res->feedback = $info["feedback"];
|
$res->feedback = $info["feedback"];
|
||||||
$res->reply = NULL; # Ответы на комментарии не реализованы
|
$res->reply = null; # Ответы на комментарии не реализованы
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Notifications;
|
namespace openvk\Web\Models\Entities\Notifications;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\{User, Club, Post};
|
use openvk\Web\Models\Entities\{User, Club, Post};
|
||||||
|
|
||||||
final class PostAcceptedNotification extends Notification
|
final class PostAcceptedNotification extends Notification
|
||||||
{
|
{
|
||||||
protected $actionCode = 6;
|
protected $actionCode = 6;
|
||||||
|
|
||||||
function __construct(User $author, Post $post, Club $group)
|
public function __construct(User $author, Post $post, Club $group)
|
||||||
{
|
{
|
||||||
parent::__construct($author, $post, $group, time(), "");
|
parent::__construct($author, $post, $group, time(), "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Notifications;
|
namespace openvk\Web\Models\Entities\Notifications;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
|
|
||||||
final class RatingUpNotification extends Notification
|
final class RatingUpNotification extends Notification
|
||||||
{
|
{
|
||||||
protected $actionCode = 9603;
|
protected $actionCode = 9603;
|
||||||
|
|
||||||
function __construct(User $receiver, User $sender, int $value, string $message)
|
public function __construct(User $receiver, User $sender, int $value, string $message)
|
||||||
{
|
{
|
||||||
parent::__construct($receiver, $receiver, $sender, time(), $value . " " . $message);
|
parent::__construct($receiver, $receiver, $sender, time(), $value . " " . $message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Notifications;
|
namespace openvk\Web\Models\Entities\Notifications;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\{User, Post};
|
use openvk\Web\Models\Entities\{User, Post};
|
||||||
|
|
||||||
final class RepostNotification extends Notification
|
final class RepostNotification extends Notification
|
||||||
{
|
{
|
||||||
protected $actionCode = 1;
|
protected $actionCode = 1;
|
||||||
protected $threshold = 120;
|
protected $threshold = 120;
|
||||||
|
|
||||||
function __construct(User $recipient, Post $post, User $reposter)
|
public function __construct(User $recipient, Post $post, User $reposter)
|
||||||
{
|
{
|
||||||
parent::__construct($recipient, $post, $reposter, time(), "");
|
parent::__construct($recipient, $post, $reposter, time(), "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Notifications;
|
namespace openvk\Web\Models\Entities\Notifications;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\{User, Post};
|
use openvk\Web\Models\Entities\{User, Post};
|
||||||
|
|
||||||
final class WallPostNotification extends Notification
|
final class WallPostNotification extends Notification
|
||||||
{
|
{
|
||||||
protected $actionCode = 3;
|
protected $actionCode = 3;
|
||||||
|
|
||||||
function __construct(User $recipient, Post $post, User $poster)
|
public function __construct(User $recipient, Post $post, User $poster)
|
||||||
{
|
{
|
||||||
parent::__construct($recipient, $post, $poster, time(), ovk_proc_strtr($post->getText(), 10));
|
parent::__construct($recipient, $post, $poster, time(), ovk_proc_strtr($post->getText(), 10));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Models\Repositories\Users;
|
use openvk\Web\Models\Repositories\Users;
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
|
@ -7,58 +11,58 @@ use openvk\Web\Util\DateTime;
|
||||||
class PasswordReset extends RowModel
|
class PasswordReset extends RowModel
|
||||||
{
|
{
|
||||||
protected $tableName = "password_resets";
|
protected $tableName = "password_resets";
|
||||||
|
|
||||||
function getUser(): User
|
public function getUser(): User
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getRecord()->profile);
|
return (new Users())->get($this->getRecord()->profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getKey(): string
|
public function getKey(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->key;
|
return $this->getRecord()->key;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getToken(): string
|
public function getToken(): string
|
||||||
{
|
{
|
||||||
return $this->getKey();
|
return $this->getKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCreationTime(): DateTime
|
public function getCreationTime(): DateTime
|
||||||
{
|
{
|
||||||
return new DateTime($this->getRecord()->timestamp);
|
return new DateTime($this->getRecord()->timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User can request password reset only if he does not have any "new" password resets.
|
* User can request password reset only if he does not have any "new" password resets.
|
||||||
* Password reset becomes "old" after 5 minutes and one second.
|
* Password reset becomes "old" after 5 minutes and one second.
|
||||||
*/
|
*/
|
||||||
function isNew(): bool
|
public function isNew(): bool
|
||||||
{
|
{
|
||||||
return $this->getRecord()->timestamp > (time() - (5 * MINUTE));
|
return $this->getRecord()->timestamp > (time() - (5 * MINUTE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Token is valid only for 3 days.
|
* Token is valid only for 3 days.
|
||||||
*/
|
*/
|
||||||
function isStillValid(): bool
|
public function isStillValid(): bool
|
||||||
{
|
{
|
||||||
return $this->getRecord()->timestamp > (time() - (3 * DAY));
|
return $this->getRecord()->timestamp > (time() - (3 * DAY));
|
||||||
}
|
}
|
||||||
|
|
||||||
function verify(string $token): bool
|
public function verify(string $token): bool
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return $this->isStillValid() ? sodium_memcmp($this->getKey(), $token) : false;
|
return $this->isStillValid() ? sodium_memcmp($this->getKey(), $token) : false;
|
||||||
} catch(\SodiumException $ex) {
|
} catch (\SodiumException $ex) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function save(?bool $log = false): void
|
public function save(?bool $log = false): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("key", base64_encode(openssl_random_pseudo_bytes(46)));
|
$this->stateChanges("key", base64_encode(openssl_random_pseudo_bytes(46)));
|
||||||
$this->stateChanges("timestamp", time());
|
$this->stateChanges("timestamp", time());
|
||||||
|
|
||||||
parent::save($log);
|
parent::save($log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use MessagePack\MessagePack;
|
use MessagePack\MessagePack;
|
||||||
use Nette\Utils\ImageException;
|
use Nette\Utils\ImageException;
|
||||||
use Nette\Utils\UnknownImageFileException;
|
use Nette\Utils\UnknownImageFileException;
|
||||||
|
@ -14,8 +18,8 @@ class Photo extends Media
|
||||||
protected $tableName = "photos";
|
protected $tableName = "photos";
|
||||||
protected $fileExtension = "jpeg";
|
protected $fileExtension = "jpeg";
|
||||||
|
|
||||||
const ALLOWED_SIDE_MULTIPLIER = 7;
|
public const ALLOWED_SIDE_MULTIPLIER = 7;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \ImagickException
|
* @throws \ImagickException
|
||||||
* @throws ImageException
|
* @throws ImageException
|
||||||
|
@ -25,70 +29,78 @@ class Photo extends Media
|
||||||
{
|
{
|
||||||
$res = [false];
|
$res = [false];
|
||||||
$requiresProportion = ((string) $size["requireProp"]) != "none";
|
$requiresProportion = ((string) $size["requireProp"]) != "none";
|
||||||
if($requiresProportion) {
|
if ($requiresProportion) {
|
||||||
$props = explode(":", (string) $size["requireProp"]);
|
$props = explode(":", (string) $size["requireProp"]);
|
||||||
$px = (int) $props[0];
|
$px = (int) $props[0];
|
||||||
$py = (int) $props[1];
|
$py = (int) $props[1];
|
||||||
if(($image->getImageWidth() / $image->getImageHeight()) > ($px / $py)) {
|
if (($image->getImageWidth() / $image->getImageHeight()) > ($px / $py)) {
|
||||||
$height = (int) ceil(($px * $image->getImageWidth()) / $py);
|
$height = (int) ceil(($px * $image->getImageWidth()) / $py);
|
||||||
$image->cropImage($image->getImageWidth(), $height, 0, 0);
|
$image->cropImage($image->getImageWidth(), $height, 0, 0);
|
||||||
$res[0] = true;
|
$res[0] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($size["maxSize"])) {
|
if (isset($size["maxSize"])) {
|
||||||
$maxSize = (int) $size["maxSize"];
|
$maxSize = (int) $size["maxSize"];
|
||||||
$sizes = Image::calculateSize($image->getImageWidth(), $image->getImageHeight(), $maxSize, $maxSize, Image::SHRINK_ONLY | Image::FIT);
|
$sizes = Image::calculateSize($image->getImageWidth(), $image->getImageHeight(), $maxSize, $maxSize, Image::SHRINK_ONLY | Image::FIT);
|
||||||
$image->resizeImage($sizes[0], $sizes[1], \Imagick::FILTER_HERMITE, 1);
|
$image->resizeImage($sizes[0], $sizes[1], \Imagick::FILTER_HERMITE, 1);
|
||||||
} else if(isset($size["maxResolution"])) {
|
} elseif (isset($size["maxResolution"])) {
|
||||||
$resolution = explode("x", (string) $size["maxResolution"]);
|
$resolution = explode("x", (string) $size["maxResolution"]);
|
||||||
$sizes = Image::calculateSize(
|
$sizes = Image::calculateSize(
|
||||||
$image->getImageWidth(), $image->getImageHeight(), (int) $resolution[0], (int) $resolution[1], Image::SHRINK_ONLY | Image::FIT
|
$image->getImageWidth(),
|
||||||
|
$image->getImageHeight(),
|
||||||
|
(int) $resolution[0],
|
||||||
|
(int) $resolution[1],
|
||||||
|
Image::SHRINK_ONLY | Image::FIT
|
||||||
);
|
);
|
||||||
$image->resizeImage($sizes[0], $sizes[1], \Imagick::FILTER_HERMITE, 1);
|
$image->resizeImage($sizes[0], $sizes[1], \Imagick::FILTER_HERMITE, 1);
|
||||||
} else {
|
} else {
|
||||||
throw new \RuntimeException("Malformed size description: " . (string) $size["id"]);
|
throw new \RuntimeException("Malformed size description: " . (string) $size["id"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$res[1] = $image->getImageWidth();
|
$res[1] = $image->getImageWidth();
|
||||||
$res[2] = $image->getImageHeight();
|
$res[2] = $image->getImageHeight();
|
||||||
if($res[1] <= 300 || $res[2] <= 300)
|
if ($res[1] <= 300 || $res[2] <= 300) {
|
||||||
$image->writeImage("$outputDir/$size[id].gif");
|
$image->writeImage("$outputDir/$size[id].gif");
|
||||||
else
|
} else {
|
||||||
$image->writeImage("$outputDir/$size[id].jpeg");
|
$image->writeImage("$outputDir/$size[id].jpeg");
|
||||||
|
}
|
||||||
|
|
||||||
$res[3] = true;
|
$res[3] = true;
|
||||||
$image->destroy();
|
$image->destroy();
|
||||||
unset($image);
|
unset($image);
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function saveImageResizedCopies(?\Imagick $image, string $filename, string $hash): void
|
private function saveImageResizedCopies(?\Imagick $image, string $filename, string $hash): void
|
||||||
{
|
{
|
||||||
if(!$image) {
|
if (!$image) {
|
||||||
$image = new \Imagick;
|
$image = new \Imagick();
|
||||||
$image->readImage($filename);
|
$image->readImage($filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dir = dirname($this->pathFromHash($hash));
|
$dir = dirname($this->pathFromHash($hash));
|
||||||
$dir = "$dir/$hash" . "_cropped";
|
$dir = "$dir/$hash" . "_cropped";
|
||||||
if(!is_dir($dir)) {
|
if (!is_dir($dir)) {
|
||||||
@unlink($dir); # Added to transparently bypass issues with dead pesudofolders summoned by buggy SWIFT impls (selectel)
|
@unlink($dir); # Added to transparently bypass issues with dead pesudofolders summoned by buggy SWIFT impls (selectel)
|
||||||
mkdir($dir);
|
mkdir($dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sizes = simplexml_load_file(OPENVK_ROOT . "/data/photosizes.xml");
|
$sizes = simplexml_load_file(OPENVK_ROOT . "/data/photosizes.xml");
|
||||||
if(!$sizes)
|
if (!$sizes) {
|
||||||
throw new \RuntimeException("Could not load photosizes.xml!");
|
throw new \RuntimeException("Could not load photosizes.xml!");
|
||||||
|
}
|
||||||
|
|
||||||
$sizesMeta = [];
|
$sizesMeta = [];
|
||||||
if(OPENVK_ROOT_CONF["openvk"]["preferences"]["photos"]["photoSaving"] === "quick") {
|
if (OPENVK_ROOT_CONF["openvk"]["preferences"]["photos"]["photoSaving"] === "quick") {
|
||||||
foreach($sizes->Size as $size)
|
foreach ($sizes->Size as $size) {
|
||||||
$sizesMeta[(string)$size["id"]] = [false, false, false, false];
|
$sizesMeta[(string) $size["id"]] = [false, false, false, false];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
foreach($sizes->Size as $size)
|
foreach ($sizes->Size as $size) {
|
||||||
$sizesMeta[(string)$size["id"]] = $this->resizeImage(clone $image, $dir, $size);
|
$sizesMeta[(string) $size["id"]] = $this->resizeImage(clone $image, $dir, $size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sizesMeta = MessagePack::pack($sizesMeta);
|
$sizesMeta = MessagePack::pack($sizesMeta);
|
||||||
|
@ -97,16 +109,18 @@ class Photo extends Media
|
||||||
|
|
||||||
protected function saveFile(string $filename, string $hash): bool
|
protected function saveFile(string $filename, string $hash): bool
|
||||||
{
|
{
|
||||||
$input_image = new \Imagick;
|
$input_image = new \Imagick();
|
||||||
$input_image->readImage($filename);
|
$input_image->readImage($filename);
|
||||||
$h = $input_image->getImageHeight();
|
$h = $input_image->getImageHeight();
|
||||||
$w = $input_image->getImageWidth();
|
$w = $input_image->getImageWidth();
|
||||||
if(($h >= ($w * Photo::ALLOWED_SIDE_MULTIPLIER)) || ($w >= ($h * Photo::ALLOWED_SIDE_MULTIPLIER)))
|
if (($h >= ($w * Photo::ALLOWED_SIDE_MULTIPLIER)) || ($w >= ($h * Photo::ALLOWED_SIDE_MULTIPLIER))) {
|
||||||
throw new ISE("Invalid layout: image is too wide/short");
|
throw new ISE("Invalid layout: image is too wide/short");
|
||||||
|
}
|
||||||
|
|
||||||
# gif fix 10.01.2025
|
# gif fix 10.01.2025
|
||||||
if($input_image->getImageFormat() === 'GIF')
|
if ($input_image->getImageFormat() === 'GIF') {
|
||||||
$input_image->setIteratorIndex(0);
|
$input_image->setIteratorIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
# png workaround (transparency to white)
|
# png workaround (transparency to white)
|
||||||
$image = new \Imagick();
|
$image = new \Imagick();
|
||||||
|
@ -115,66 +129,72 @@ class Photo extends Media
|
||||||
$image->compositeImage($input_image, \Imagick::COMPOSITE_OVER, 0, 0);
|
$image->compositeImage($input_image, \Imagick::COMPOSITE_OVER, 0, 0);
|
||||||
|
|
||||||
$sizes = Image::calculateSize(
|
$sizes = Image::calculateSize(
|
||||||
$image->getImageWidth(), $image->getImageHeight(), 8192, 4320, Image::SHRINK_ONLY | Image::FIT
|
$image->getImageWidth(),
|
||||||
|
$image->getImageHeight(),
|
||||||
|
8192,
|
||||||
|
4320,
|
||||||
|
Image::SHRINK_ONLY | Image::FIT
|
||||||
);
|
);
|
||||||
|
|
||||||
$image->resizeImage($sizes[0], $sizes[1], \Imagick::FILTER_HERMITE, 1);
|
$image->resizeImage($sizes[0], $sizes[1], \Imagick::FILTER_HERMITE, 1);
|
||||||
$image->writeImage($this->pathFromHash($hash));
|
$image->writeImage($this->pathFromHash($hash));
|
||||||
$this->saveImageResizedCopies($image, $filename, $hash);
|
$this->saveImageResizedCopies($image, $filename, $hash);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function crop(float $left, float $top, float $width, float $height): void
|
public function crop(float $left, float $top, float $width, float $height): void
|
||||||
{
|
{
|
||||||
if(isset($this->changes["hash"]))
|
if (isset($this->changes["hash"])) {
|
||||||
$hash = $this->changes["hash"];
|
$hash = $this->changes["hash"];
|
||||||
else if(!is_null($this->getRecord()))
|
} elseif (!is_null($this->getRecord())) {
|
||||||
$hash = $this->getRecord()->hash;
|
$hash = $this->getRecord()->hash;
|
||||||
else
|
} else {
|
||||||
throw new ISE("Cannot crop uninitialized image. Please call setFile(\$_FILES[...]) first.");
|
throw new ISE("Cannot crop uninitialized image. Please call setFile(\$_FILES[...]) first.");
|
||||||
|
}
|
||||||
|
|
||||||
$image = Image::fromFile($this->pathFromHash($hash));
|
$image = Image::fromFile($this->pathFromHash($hash));
|
||||||
$image->crop($left, $top, $width, $height);
|
$image->crop($left, $top, $width, $height);
|
||||||
$image->save($this->pathFromHash($hash));
|
$image->save($this->pathFromHash($hash));
|
||||||
}
|
}
|
||||||
|
|
||||||
function isolate(): void
|
public function isolate(): void
|
||||||
{
|
{
|
||||||
if(is_null($this->getRecord()))
|
if (is_null($this->getRecord())) {
|
||||||
throw new ISE("Cannot isolate unpresisted image. Please save() it first.");
|
throw new ISE("Cannot isolate unpresisted image. Please save() it first.");
|
||||||
|
}
|
||||||
|
|
||||||
DB::i()->getContext()->table("album_relations")->where("media", $this->getRecord()->id)->delete();
|
DB::i()->getContext()->table("album_relations")->where("media", $this->getRecord()->id)->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSizes(bool $upgrade = false, bool $forceUpdate = false): ?array
|
public function getSizes(bool $upgrade = false, bool $forceUpdate = false): ?array
|
||||||
{
|
{
|
||||||
$sizes = $this->getRecord()->sizes;
|
$sizes = $this->getRecord()->sizes;
|
||||||
if(!$sizes || $forceUpdate) {
|
if (!$sizes || $forceUpdate) {
|
||||||
if($forceUpdate || $upgrade || OPENVK_ROOT_CONF["openvk"]["preferences"]["photos"]["upgradeStructure"]) {
|
if ($forceUpdate || $upgrade || OPENVK_ROOT_CONF["openvk"]["preferences"]["photos"]["upgradeStructure"]) {
|
||||||
$hash = $this->getRecord()->hash;
|
$hash = $this->getRecord()->hash;
|
||||||
$this->saveImageResizedCopies(NULL, $this->pathFromHash($hash), $hash);
|
$this->saveImageResizedCopies(null, $this->pathFromHash($hash), $hash);
|
||||||
$this->save();
|
$this->save();
|
||||||
|
|
||||||
return $this->getSizes();
|
return $this->getSizes();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$res = [];
|
$res = [];
|
||||||
$sizes = MessagePack::unpack($sizes);
|
$sizes = MessagePack::unpack($sizes);
|
||||||
foreach($sizes as $id => $meta) {
|
foreach ($sizes as $id => $meta) {
|
||||||
if(isset($meta[3]) && !$meta[3]) {
|
if (isset($meta[3]) && !$meta[3]) {
|
||||||
$res[$id] = (object) [
|
$res[$id] = (object) [
|
||||||
"url" => ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/photos/thumbnails/" . $this->getId() . "_$id.jpeg",
|
"url" => ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/photos/thumbnails/" . $this->getId() . "_$id.jpeg",
|
||||||
"width" => NULL,
|
"width" => null,
|
||||||
"height" => NULL,
|
"height" => null,
|
||||||
"crop" => NULL
|
"crop" => null,
|
||||||
];
|
];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$url = $this->getURL();
|
$url = $this->getURL();
|
||||||
$url = str_replace(".$this->fileExtension", "_cropped/$id.", $url);
|
$url = str_replace(".$this->fileExtension", "_cropped/$id.", $url);
|
||||||
$url .= ($meta[1] <= 300 || $meta[2] <= 300) ? "gif" : "jpeg";
|
$url .= ($meta[1] <= 300 || $meta[2] <= 300) ? "gif" : "jpeg";
|
||||||
|
@ -183,7 +203,7 @@ class Photo extends Media
|
||||||
"url" => $url,
|
"url" => $url,
|
||||||
"width" => $meta[1],
|
"width" => $meta[1],
|
||||||
"height" => $meta[2],
|
"height" => $meta[2],
|
||||||
"crop" => $meta[0]
|
"crop" => $meta[0],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,69 +212,78 @@ class Photo extends Media
|
||||||
"url" => $this->getURL(),
|
"url" => $this->getURL(),
|
||||||
"width" => $x,
|
"width" => $x,
|
||||||
"height" => $y,
|
"height" => $y,
|
||||||
"crop" => false
|
"crop" => false,
|
||||||
];
|
];
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function forceSize(string $sizeName): bool
|
public function forceSize(string $sizeName): bool
|
||||||
{
|
{
|
||||||
$hash = $this->getRecord()->hash;
|
$hash = $this->getRecord()->hash;
|
||||||
$sizes = MessagePack::unpack($this->getRecord()->sizes);
|
$sizes = MessagePack::unpack($this->getRecord()->sizes);
|
||||||
$size = $sizes[$sizeName] ?? false;
|
$size = $sizes[$sizeName] ?? false;
|
||||||
if(!$size)
|
if (!$size) {
|
||||||
return $size;
|
return $size;
|
||||||
|
}
|
||||||
if(!isset($size[3]) || $size[3] === true)
|
|
||||||
|
if (!isset($size[3]) || $size[3] === true) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
$path = $this->pathFromHash($hash);
|
$path = $this->pathFromHash($hash);
|
||||||
$dir = dirname($this->pathFromHash($hash));
|
$dir = dirname($this->pathFromHash($hash));
|
||||||
$dir = "$dir/$hash" . "_cropped";
|
$dir = "$dir/$hash" . "_cropped";
|
||||||
if(!is_dir($dir)) {
|
if (!is_dir($dir)) {
|
||||||
@unlink($dir);
|
@unlink($dir);
|
||||||
mkdir($dir);
|
mkdir($dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sizeMetas = simplexml_load_file(OPENVK_ROOT . "/data/photosizes.xml");
|
$sizeMetas = simplexml_load_file(OPENVK_ROOT . "/data/photosizes.xml");
|
||||||
if(!$sizeMetas)
|
if (!$sizeMetas) {
|
||||||
throw new \RuntimeException("Could not load photosizes.xml!");
|
throw new \RuntimeException("Could not load photosizes.xml!");
|
||||||
|
}
|
||||||
$sizeInfo = NULL;
|
|
||||||
foreach($sizeMetas->Size as $size)
|
$sizeInfo = null;
|
||||||
if($size["id"] == $sizeName)
|
foreach ($sizeMetas->Size as $size) {
|
||||||
|
if ($size["id"] == $sizeName) {
|
||||||
$sizeInfo = $size;
|
$sizeInfo = $size;
|
||||||
|
}
|
||||||
if(!$sizeInfo)
|
}
|
||||||
|
|
||||||
|
if (!$sizeInfo) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
$pic = new \Imagick;
|
|
||||||
|
$pic = new \Imagick();
|
||||||
$pic->readImage($path);
|
$pic->readImage($path);
|
||||||
$sizes[$sizeName] = $this->resizeImage($pic, $dir, $sizeInfo);
|
$sizes[$sizeName] = $this->resizeImage($pic, $dir, $sizeInfo);
|
||||||
|
|
||||||
$this->stateChanges("sizes", MessagePack::pack($sizes));
|
$this->stateChanges("sizes", MessagePack::pack($sizes));
|
||||||
$this->save();
|
$this->save();
|
||||||
|
|
||||||
return $sizes[$sizeName][3];
|
return $sizes[$sizeName][3];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVkApiSizes(): ?array
|
public function getVkApiSizes(): ?array
|
||||||
{
|
{
|
||||||
$res = [];
|
$res = [];
|
||||||
$sizes = $this->getSizes();
|
$sizes = $this->getSizes();
|
||||||
if(!$sizes)
|
if (!$sizes) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
$manifest = simplexml_load_file(OPENVK_ROOT . "/data/photosizes.xml");
|
$manifest = simplexml_load_file(OPENVK_ROOT . "/data/photosizes.xml");
|
||||||
if(!$manifest)
|
if (!$manifest) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
$mappings = [];
|
$mappings = [];
|
||||||
foreach($manifest->Size as $size)
|
foreach ($manifest->Size as $size) {
|
||||||
$mappings[(string) $size["id"]] = (string) $size["vkId"];
|
$mappings[(string) $size["id"]] = (string) $size["vkId"];
|
||||||
|
}
|
||||||
|
|
||||||
foreach($sizes as $id => $meta) {
|
foreach ($sizes as $id => $meta) {
|
||||||
$type = $mappings[$id] ?? $id;
|
$type = $mappings[$id] ?? $id;
|
||||||
$meta->type = $type;
|
$meta->type = $type;
|
||||||
$res[$type] = $meta;
|
$res[$type] = $meta;
|
||||||
|
@ -263,24 +292,26 @@ class Photo extends Media
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getURLBySizeId(string $size): string
|
public function getURLBySizeId(string $size): string
|
||||||
{
|
{
|
||||||
$sizes = $this->getSizes();
|
$sizes = $this->getSizes();
|
||||||
if(!$sizes)
|
if (!$sizes) {
|
||||||
return $this->getURL();
|
return $this->getURL();
|
||||||
|
}
|
||||||
|
|
||||||
$size = $sizes[$size];
|
$size = $sizes[$size];
|
||||||
if(!$size)
|
if (!$size) {
|
||||||
return $this->getURL();
|
return $this->getURL();
|
||||||
|
}
|
||||||
|
|
||||||
return $size->url;
|
return $size->url;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDimensions(): array
|
public function getDimensions(): array
|
||||||
{
|
{
|
||||||
$x = $this->getRecord()->width;
|
$x = $this->getRecord()->width;
|
||||||
$y = $this->getRecord()->height;
|
$y = $this->getRecord()->height;
|
||||||
if(!$x) { # no sizes in database
|
if (!$x) { # no sizes in database
|
||||||
$hash = $this->getRecord()->hash;
|
$hash = $this->getRecord()->hash;
|
||||||
$image = Image::fromFile($this->pathFromHash($hash));
|
$image = Image::fromFile($this->pathFromHash($hash));
|
||||||
|
|
||||||
|
@ -294,31 +325,32 @@ class Photo extends Media
|
||||||
return [$x, $y];
|
return [$x, $y];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPageURL(): string
|
public function getPageURL(): string
|
||||||
{
|
{
|
||||||
if($this->isAnonymous())
|
if ($this->isAnonymous()) {
|
||||||
return "/photos/" . base_convert((string) $this->getId(), 10, 32);
|
return "/photos/" . base_convert((string) $this->getId(), 10, 32);
|
||||||
|
}
|
||||||
|
|
||||||
return "/photo" . $this->getPrettyId();
|
return "/photo" . $this->getPrettyId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAlbum(): ?Album
|
public function getAlbum(): ?Album
|
||||||
{
|
{
|
||||||
return (new Albums)->getAlbumByPhotoId($this);
|
return (new Albums())->getAlbumByPhotoId($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toVkApiStruct(bool $photo_sizes = true, bool $extended = false): object
|
public function toVkApiStruct(bool $photo_sizes = true, bool $extended = false): object
|
||||||
{
|
{
|
||||||
$res = (object) [];
|
$res = (object) [];
|
||||||
|
|
||||||
$res->id = $res->pid = $this->getVirtualId();
|
$res->id = $res->pid = $this->getVirtualId();
|
||||||
$res->owner_id = $res->user_id = $this->getOwner()->getId();
|
$res->owner_id = $res->user_id = $this->getOwner()->getId();
|
||||||
$res->aid = $res->album_id = NULL;
|
$res->aid = $res->album_id = null;
|
||||||
$res->width = $this->getDimensions()[0];
|
$res->width = $this->getDimensions()[0];
|
||||||
$res->height = $this->getDimensions()[1];
|
$res->height = $this->getDimensions()[1];
|
||||||
$res->date = $res->created = $this->getPublicationTime()->timestamp();
|
$res->date = $res->created = $this->getPublicationTime()->timestamp();
|
||||||
|
|
||||||
if($photo_sizes) {
|
if ($photo_sizes) {
|
||||||
$res->sizes = array_values($this->getVkApiSizes());
|
$res->sizes = array_values($this->getVkApiSizes());
|
||||||
$res->src_small = $res->photo_75 = $this->getURLBySizeId("miniscule");
|
$res->src_small = $res->photo_75 = $this->getURLBySizeId("miniscule");
|
||||||
$res->src = $res->photo_130 = $this->getURLBySizeId("tiny");
|
$res->src = $res->photo_130 = $this->getURLBySizeId("tiny");
|
||||||
|
@ -329,7 +361,7 @@ class Photo extends Media
|
||||||
$res->src_original = $res->url = $this->getURLBySizeId("UPLOADED_MAXRES");
|
$res->src_original = $res->url = $this->getURLBySizeId("UPLOADED_MAXRES");
|
||||||
}
|
}
|
||||||
|
|
||||||
if($extended) {
|
if ($extended) {
|
||||||
$res->likes = $this->getLikesCount(); # их нету но пусть будут
|
$res->likes = $this->getLikesCount(); # их нету но пусть будут
|
||||||
$res->comments = $this->getCommentsCount();
|
$res->comments = $this->getCommentsCount();
|
||||||
$res->tags = 0;
|
$res->tags = 0;
|
||||||
|
@ -339,23 +371,23 @@ class Photo extends Media
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBeViewedBy(?User $user = NULL): bool
|
public function canBeViewedBy(?User $user = null): bool
|
||||||
{
|
{
|
||||||
if($this->isDeleted() || $this->getOwner()->isDeleted()) {
|
if ($this->isDeleted() || $this->getOwner()->isDeleted()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!is_null($this->getAlbum())) {
|
if (!is_null($this->getAlbum())) {
|
||||||
return $this->getAlbum()->canBeViewedBy($user);
|
return $this->getAlbum()->canBeViewedBy($user);
|
||||||
} else {
|
} else {
|
||||||
return $this->getOwner()->canBeViewedBy($user);
|
return $this->getOwner()->canBeViewedBy($user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static function fastMake(int $owner, string $description = "", array $file, ?Album $album = NULL, bool $anon = false): Photo
|
public static function fastMake(int $owner, string $description = "", array $file, ?Album $album = null, bool $anon = false): Photo
|
||||||
{
|
{
|
||||||
$photo = new static;
|
$photo = new static();
|
||||||
$photo->setOwner($owner);
|
$photo->setOwner($owner);
|
||||||
$photo->setDescription(iconv_substr($description, 0, 36) . "...");
|
$photo->setDescription(iconv_substr($description, 0, 36) . "...");
|
||||||
$photo->setAnonymous($anon);
|
$photo->setAnonymous($anon);
|
||||||
|
@ -363,7 +395,7 @@ class Photo extends Media
|
||||||
$photo->setFile($file);
|
$photo->setFile($file);
|
||||||
$photo->save();
|
$photo->save();
|
||||||
|
|
||||||
if(!is_null($album)) {
|
if (!is_null($album)) {
|
||||||
$album->addPhoto($photo);
|
$album->addPhoto($photo);
|
||||||
$album->setEdited(time());
|
$album->setEdited(time());
|
||||||
$album->save();
|
$album->save();
|
||||||
|
@ -372,10 +404,10 @@ class Photo extends Media
|
||||||
return $photo;
|
return $photo;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toNotifApiStruct()
|
public function toNotifApiStruct()
|
||||||
{
|
{
|
||||||
$res = (object)[];
|
$res = (object) [];
|
||||||
|
|
||||||
$res->id = $this->getVirtualId();
|
$res->id = $this->getVirtualId();
|
||||||
$res->owner_id = $this->getOwner()->getId();
|
$res->owner_id = $this->getOwner()->getId();
|
||||||
$res->aid = 0;
|
$res->aid = 0;
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use Chandler\Database\DatabaseConnection;
|
use Chandler\Database\DatabaseConnection;
|
||||||
use Nette\Database\Table\ActiveRow;
|
use Nette\Database\Table\ActiveRow;
|
||||||
use openvk\Web\Models\Repositories\Audios;
|
use openvk\Web\Models\Repositories\Audios;
|
||||||
|
@ -21,64 +25,68 @@ class Playlist extends MediaCollection
|
||||||
|
|
||||||
private $importTable;
|
private $importTable;
|
||||||
|
|
||||||
const MAX_COUNT = 1000;
|
public const MAX_COUNT = 1000;
|
||||||
const MAX_ITEMS = 10000;
|
public const MAX_ITEMS = 10000;
|
||||||
|
|
||||||
function __construct(?ActiveRow $ar = NULL)
|
public function __construct(?ActiveRow $ar = null)
|
||||||
{
|
{
|
||||||
parent::__construct($ar);
|
parent::__construct($ar);
|
||||||
|
|
||||||
$this->importTable = DatabaseConnection::i()->getContext()->table("playlist_imports");
|
$this->importTable = DatabaseConnection::i()->getContext()->table("playlist_imports");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCoverURL(string $size = "normal"): ?string
|
public function getCoverURL(string $size = "normal"): ?string
|
||||||
{
|
{
|
||||||
$photo = (new Photos)->get((int) $this->getRecord()->cover_photo_id);
|
$photo = (new Photos())->get((int) $this->getRecord()->cover_photo_id);
|
||||||
return is_null($photo) ? "/assets/packages/static/openvk/img/song.jpg" : $photo->getURLBySizeId($size);
|
return is_null($photo) ? "/assets/packages/static/openvk/img/song.jpg" : $photo->getURLBySizeId($size);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLength(): int
|
public function getLength(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->length;
|
return $this->getRecord()->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchClassic(int $offset = 0, ?int $limit = NULL): \Traversable
|
public function fetchClassic(int $offset = 0, ?int $limit = null): \Traversable
|
||||||
{
|
{
|
||||||
$related = $this->getRecord()->related("$this->relTableName.collection")
|
$related = $this->getRecord()->related("$this->relTableName.collection")
|
||||||
->limit($limit ?? OPENVK_DEFAULT_PER_PAGE, $offset)
|
->limit($limit ?? OPENVK_DEFAULT_PER_PAGE, $offset)
|
||||||
->order("index ASC");
|
->order("index ASC");
|
||||||
|
|
||||||
foreach($related as $rel) {
|
foreach ($related as $rel) {
|
||||||
$media = $rel->ref($this->entityTableName, "media");
|
$media = $rel->ref($this->entityTableName, "media");
|
||||||
if(!$media)
|
if (!$media) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
yield new $this->entityClassName($media);
|
yield new $this->entityClassName($media);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAudios(int $offset = 0, ?int $limit = NULL, ?int $shuffleSeed = NULL): \Traversable
|
public function getAudios(int $offset = 0, ?int $limit = null, ?int $shuffleSeed = null): \Traversable
|
||||||
{
|
{
|
||||||
if(!$shuffleSeed) {
|
if (!$shuffleSeed) {
|
||||||
foreach ($this->fetchClassic($offset, $limit) as $e)
|
foreach ($this->fetchClassic($offset, $limit) as $e) {
|
||||||
yield $e; # No, I can't return, it will break with []
|
yield $e;
|
||||||
|
} # No, I can't return, it will break with []
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$ids = [];
|
$ids = [];
|
||||||
foreach($this->relations->select("media AS i")->where("collection", $this->getId()) as $rel)
|
foreach ($this->relations->select("media AS i")->where("collection", $this->getId()) as $rel) {
|
||||||
$ids[] = $rel->i;
|
$ids[] = $rel->i;
|
||||||
|
}
|
||||||
|
|
||||||
$ids = knuth_shuffle($ids, $shuffleSeed);
|
$ids = knuth_shuffle($ids, $shuffleSeed);
|
||||||
$ids = array_slice($ids, $offset, $limit ?? OPENVK_DEFAULT_PER_PAGE);
|
$ids = array_slice($ids, $offset, $limit ?? OPENVK_DEFAULT_PER_PAGE);
|
||||||
foreach($ids as $id)
|
foreach ($ids as $id) {
|
||||||
yield (new Audios)->get($id);
|
yield (new Audios())->get($id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function add(RowModel $audio): bool
|
public function add(RowModel $audio): bool
|
||||||
{
|
{
|
||||||
if($res = parent::add($audio)) {
|
if ($res = parent::add($audio)) {
|
||||||
$this->stateChanges("length", $this->getRecord()->length + $audio->getLength());
|
$this->stateChanges("length", $this->getRecord()->length + $audio->getLength());
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
}
|
||||||
|
@ -86,9 +94,9 @@ class Playlist extends MediaCollection
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function remove(RowModel $audio): bool
|
public function remove(RowModel $audio): bool
|
||||||
{
|
{
|
||||||
if($res = parent::remove($audio)) {
|
if ($res = parent::remove($audio)) {
|
||||||
$this->stateChanges("length", $this->getRecord()->length - $audio->getLength());
|
$this->stateChanges("length", $this->getRecord()->length - $audio->getLength());
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
}
|
||||||
|
@ -96,11 +104,12 @@ class Playlist extends MediaCollection
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isBookmarkedBy(RowModel $entity): bool
|
public function isBookmarkedBy(RowModel $entity): bool
|
||||||
{
|
{
|
||||||
$id = $entity->getId();
|
$id = $entity->getId();
|
||||||
if($entity instanceof Club)
|
if ($entity instanceof Club) {
|
||||||
$id *= -1;
|
$id *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
return !is_null($this->importTable->where([
|
return !is_null($this->importTable->where([
|
||||||
"entity" => $id,
|
"entity" => $id,
|
||||||
|
@ -108,17 +117,20 @@ class Playlist extends MediaCollection
|
||||||
])->fetch());
|
])->fetch());
|
||||||
}
|
}
|
||||||
|
|
||||||
function bookmark(RowModel $entity): bool
|
public function bookmark(RowModel $entity): bool
|
||||||
{
|
{
|
||||||
if($this->isBookmarkedBy($entity))
|
if ($this->isBookmarkedBy($entity)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$id = $entity->getId();
|
$id = $entity->getId();
|
||||||
if($entity instanceof Club)
|
if ($entity instanceof Club) {
|
||||||
$id *= -1;
|
$id *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
if($this->importTable->where("entity", $id)->count() > self::MAX_COUNT)
|
if ($this->importTable->where("entity", $id)->count() > self::MAX_COUNT) {
|
||||||
throw new \OutOfBoundsException("Maximum amount of playlists");
|
throw new \OutOfBoundsException("Maximum amount of playlists");
|
||||||
|
}
|
||||||
|
|
||||||
$this->importTable->insert([
|
$this->importTable->insert([
|
||||||
"entity" => $id,
|
"entity" => $id,
|
||||||
|
@ -128,11 +140,12 @@ class Playlist extends MediaCollection
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function unbookmark(RowModel $entity): bool
|
public function unbookmark(RowModel $entity): bool
|
||||||
{
|
{
|
||||||
$id = $entity->getId();
|
$id = $entity->getId();
|
||||||
if($entity instanceof Club)
|
if ($entity instanceof Club) {
|
||||||
$id *= -1;
|
$id *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
$count = $this->importTable->where([
|
$count = $this->importTable->where([
|
||||||
"entity" => $id,
|
"entity" => $id,
|
||||||
|
@ -141,27 +154,28 @@ class Playlist extends MediaCollection
|
||||||
|
|
||||||
return $count > 0;
|
return $count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDescription(): ?string
|
public function getDescription(): ?string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->description;
|
return $this->getRecord()->description;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDescriptionHTML(): ?string
|
public function getDescriptionHTML(): ?string
|
||||||
{
|
{
|
||||||
return htmlspecialchars($this->getRecord()->description, ENT_DISALLOWED | ENT_XHTML);
|
return htmlspecialchars($this->getRecord()->description, ENT_DISALLOWED | ENT_XHTML);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getListens()
|
public function getListens()
|
||||||
{
|
{
|
||||||
return $this->getRecord()->listens;
|
return $this->getRecord()->listens;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toVkApiStruct(?User $user = NULL): object
|
public function toVkApiStruct(?User $user = null): object
|
||||||
{
|
{
|
||||||
$oid = $this->getOwner()->getId();
|
$oid = $this->getOwner()->getId();
|
||||||
if($this->getOwner() instanceof Club)
|
if ($this->getOwner() instanceof Club) {
|
||||||
$oid *= -1;
|
$oid *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
"id" => $this->getId(),
|
"id" => $this->getId(),
|
||||||
|
@ -171,7 +185,7 @@ class Playlist extends MediaCollection
|
||||||
"size" => $this->size(),
|
"size" => $this->size(),
|
||||||
"length" => $this->getLength(),
|
"length" => $this->getLength(),
|
||||||
"created" => $this->getCreationTime()->timestamp(),
|
"created" => $this->getCreationTime()->timestamp(),
|
||||||
"modified" => $this->getEditTime() ? $this->getEditTime()->timestamp() : NULL,
|
"modified" => $this->getEditTime() ? $this->getEditTime()->timestamp() : null,
|
||||||
"accessible" => $this->canBeViewedBy($user),
|
"accessible" => $this->canBeViewedBy($user),
|
||||||
"editable" => $this->canBeModifiedBy($user),
|
"editable" => $this->canBeModifiedBy($user),
|
||||||
"bookmarked" => $this->isBookmarkedBy($user),
|
"bookmarked" => $this->isBookmarkedBy($user),
|
||||||
|
@ -181,19 +195,19 @@ class Playlist extends MediaCollection
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLength(): void
|
public function setLength(): void
|
||||||
{
|
{
|
||||||
throw new \LogicException("Can't set length of playlist manually");
|
throw new \LogicException("Can't set length of playlist manually");
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetLength(): bool
|
public function resetLength(): bool
|
||||||
{
|
{
|
||||||
$this->stateChanges("length", 0);
|
$this->stateChanges("length", 0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete(bool $softly = true): void
|
public function delete(bool $softly = true): void
|
||||||
{
|
{
|
||||||
$ctx = DatabaseConnection::i()->getContext();
|
$ctx = DatabaseConnection::i()->getContext();
|
||||||
$ctx->table("playlist_imports")->where("playlist", $this->getId())
|
$ctx->table("playlist_imports")->where("playlist", $this->getId())
|
||||||
|
@ -202,44 +216,46 @@ class Playlist extends MediaCollection
|
||||||
parent::delete($softly);
|
parent::delete($softly);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasAudio(Audio $audio): bool
|
public function hasAudio(Audio $audio): bool
|
||||||
{
|
{
|
||||||
$ctx = DatabaseConnection::i()->getContext();
|
$ctx = DatabaseConnection::i()->getContext();
|
||||||
return !is_null($ctx->table("playlist_relations")->where([
|
return !is_null($ctx->table("playlist_relations")->where([
|
||||||
"collection" => $this->getId(),
|
"collection" => $this->getId(),
|
||||||
"media" => $audio->getId()
|
"media" => $audio->getId(),
|
||||||
])->fetch());
|
])->fetch());
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCoverPhotoId(): ?int
|
public function getCoverPhotoId(): ?int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->cover_photo_id;
|
return $this->getRecord()->cover_photo_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCoverPhoto(): ?Photo
|
public function getCoverPhoto(): ?Photo
|
||||||
{
|
{
|
||||||
return (new Photos)->get((int) $this->getRecord()->cover_photo_id);
|
return (new Photos())->get((int) $this->getRecord()->cover_photo_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBeModifiedBy(User $user): bool
|
public function canBeModifiedBy(User $user): bool
|
||||||
{
|
{
|
||||||
if(!$user)
|
if (!$user) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if($this->getOwner() instanceof User)
|
if ($this->getOwner() instanceof User) {
|
||||||
return $user->getId() == $this->getOwner()->getId();
|
return $user->getId() == $this->getOwner()->getId();
|
||||||
else
|
} else {
|
||||||
return $this->getOwner()->canBeModifiedBy($user);
|
return $this->getOwner()->canBeModifiedBy($user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLengthInMinutes(): int
|
public function getLengthInMinutes(): int
|
||||||
{
|
{
|
||||||
return (int)round($this->getLength() / 60, PHP_ROUND_HALF_DOWN);
|
return (int) round($this->getLength() / 60, PHP_ROUND_HALF_DOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
function fastMakeCover(int $owner, array $file)
|
public function fastMakeCover(int $owner, array $file)
|
||||||
{
|
{
|
||||||
$cover = new Photo;
|
$cover = new Photo();
|
||||||
$cover->setOwner($owner);
|
$cover->setOwner($owner);
|
||||||
$cover->setDescription("Playlist cover image");
|
$cover->setDescription("Playlist cover image");
|
||||||
$cover->setFile($file);
|
$cover->setFile($file);
|
||||||
|
@ -251,32 +267,34 @@ class Playlist extends MediaCollection
|
||||||
return $cover;
|
return $cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getURL(): string
|
public function getURL(): string
|
||||||
{
|
{
|
||||||
return "/playlist" . $this->getOwner()->getRealId() . "_" . $this->getId();
|
return "/playlist" . $this->getOwner()->getRealId() . "_" . $this->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function incrementListens()
|
public function incrementListens()
|
||||||
{
|
{
|
||||||
$this->stateChanges("listens", ($this->getListens() + 1));
|
$this->stateChanges("listens", ($this->getListens() + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMetaDescription(): string
|
public function getMetaDescription(): string
|
||||||
{
|
{
|
||||||
$length = $this->getLengthInMinutes();
|
$length = $this->getLengthInMinutes();
|
||||||
|
|
||||||
$props = [];
|
$props = [];
|
||||||
$props[] = tr("audios_count", $this->size());
|
$props[] = tr("audios_count", $this->size());
|
||||||
$props[] = "<span id='listensCount'>" . tr("listens_count", $this->getListens()) . "</span>";
|
$props[] = "<span id='listensCount'>" . tr("listens_count", $this->getListens()) . "</span>";
|
||||||
if($length > 0) $props[] = tr("minutes_count", $length);
|
if ($length > 0) {
|
||||||
|
$props[] = tr("minutes_count", $length);
|
||||||
|
}
|
||||||
$props[] = tr("created_playlist") . " " . $this->getPublicationTime();
|
$props[] = tr("created_playlist") . " " . $this->getPublicationTime();
|
||||||
# if($this->getEditTime()) $props[] = tr("updated_playlist") . " " . $this->getEditTime();
|
# if($this->getEditTime()) $props[] = tr("updated_playlist") . " " . $this->getEditTime();
|
||||||
|
|
||||||
return implode(" • ", $props);
|
return implode(" • ", $props);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isUnlisted(): bool
|
public function isUnlisted(): bool
|
||||||
{
|
{
|
||||||
return (bool)$this->getRecord()->unlisted;
|
return (bool) $this->getRecord()->unlisted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Models\Exceptions\TooMuchOptionsException;
|
use openvk\Web\Models\Exceptions\TooMuchOptionsException;
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
use \UnexpectedValueException;
|
use UnexpectedValueException;
|
||||||
use Nette\InvalidStateException;
|
use Nette\InvalidStateException;
|
||||||
use openvk\Web\Models\Repositories\{Users, Posts};
|
use openvk\Web\Models\Repositories\{Users, Posts};
|
||||||
use Chandler\Database\DatabaseConnection;
|
use Chandler\Database\DatabaseConnection;
|
||||||
|
@ -13,178 +17,198 @@ use openvk\Web\Models\Exceptions\InvalidOptionException;
|
||||||
class Poll extends Attachable
|
class Poll extends Attachable
|
||||||
{
|
{
|
||||||
protected $tableName = "polls";
|
protected $tableName = "polls";
|
||||||
|
|
||||||
private $choicesToPersist = [];
|
private $choicesToPersist = [];
|
||||||
|
|
||||||
function getTitle(): string
|
public function getTitle(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->title;
|
return $this->getRecord()->title;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMetaDescription(): string
|
public function getMetaDescription(): string
|
||||||
{
|
{
|
||||||
$props = [];
|
$props = [];
|
||||||
$props[] = tr($this->isAnonymous() ? "poll_anon" : "poll_public");
|
$props[] = tr($this->isAnonymous() ? "poll_anon" : "poll_public");
|
||||||
if($this->isMultipleChoice()) $props[] = tr("poll_multi");
|
if ($this->isMultipleChoice()) {
|
||||||
if(!$this->isRevotable()) $props[] = tr("poll_lock");
|
$props[] = tr("poll_multi");
|
||||||
if(!is_null($this->endsAt())) $props[] = tr("poll_until", $this->endsAt());
|
}
|
||||||
|
if (!$this->isRevotable()) {
|
||||||
|
$props[] = tr("poll_lock");
|
||||||
|
}
|
||||||
|
if (!is_null($this->endsAt())) {
|
||||||
|
$props[] = tr("poll_until", $this->endsAt());
|
||||||
|
}
|
||||||
|
|
||||||
return implode(" • ", $props);
|
return implode(" • ", $props);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOwner(): User
|
public function getOwner(): User
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getRecord()->owner);
|
return (new Users())->get($this->getRecord()->owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOptions(): array
|
public function getOptions(): array
|
||||||
{
|
{
|
||||||
$options = $this->getRecord()->related("poll_options.poll");
|
$options = $this->getRecord()->related("poll_options.poll");
|
||||||
$res = [];
|
$res = [];
|
||||||
foreach($options as $opt)
|
foreach ($options as $opt) {
|
||||||
$res[$opt->id] = $opt->name;
|
$res[$opt->id] = $opt->name;
|
||||||
|
}
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUserVote(User $user): ?array
|
public function getUserVote(User $user): ?array
|
||||||
{
|
{
|
||||||
$ctx = DatabaseConnection::i()->getContext();
|
$ctx = DatabaseConnection::i()->getContext();
|
||||||
$votedOpts = $ctx->table("poll_votes")
|
$votedOpts = $ctx->table("poll_votes")
|
||||||
->where(["user" => $user->getId(), "poll" => $this->getId()]);
|
->where(["user" => $user->getId(), "poll" => $this->getId()]);
|
||||||
|
|
||||||
if($votedOpts->count() == 0)
|
if ($votedOpts->count() == 0) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
$res = [];
|
$res = [];
|
||||||
foreach($votedOpts as $votedOpt) {
|
foreach ($votedOpts as $votedOpt) {
|
||||||
$option = $ctx->table("poll_options")->get($votedOpt->option);
|
$option = $ctx->table("poll_options")->get($votedOpt->option);
|
||||||
$res[] = [$option->id, $option->name];
|
$res[] = [$option->id, $option->name];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVoters(int $optionId, int $page = 1, ?int $perPage = NULL): array
|
public function getVoters(int $optionId, int $page = 1, ?int $perPage = null): array
|
||||||
{
|
{
|
||||||
$res = [];
|
$res = [];
|
||||||
$ctx = DatabaseConnection::i()->getContext();
|
$ctx = DatabaseConnection::i()->getContext();
|
||||||
$perPage = $perPage ?? OPENVK_DEFAULT_PER_PAGE;
|
$perPage ??= OPENVK_DEFAULT_PER_PAGE;
|
||||||
$voters = $ctx->table("poll_votes")->where(["poll" => $this->getId(), "option" => $optionId]);
|
$voters = $ctx->table("poll_votes")->where(["poll" => $this->getId(), "option" => $optionId]);
|
||||||
foreach($voters->page($page, $perPage) as $vote)
|
foreach ($voters->page($page, $perPage) as $vote) {
|
||||||
$res[] = (new Users)->get($vote->user);
|
$res[] = (new Users())->get($vote->user);
|
||||||
|
}
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVoterCount(?int $optionId = NULL): int
|
public function getVoterCount(?int $optionId = null): int
|
||||||
{
|
{
|
||||||
$votes = DatabaseConnection::i()->getContext()->table("poll_votes");
|
$votes = DatabaseConnection::i()->getContext()->table("poll_votes");
|
||||||
if(!$optionId)
|
if (!$optionId) {
|
||||||
return $votes->select("COUNT(DISTINCT user) AS c")->where("poll", $this->getId())->fetch()->c;
|
return $votes->select("COUNT(DISTINCT user) AS c")->where("poll", $this->getId())->fetch()->c;
|
||||||
|
}
|
||||||
|
|
||||||
return $votes->where(["poll" => $this->getId(), "option" => $optionId])->count();
|
return $votes->where(["poll" => $this->getId(), "option" => $optionId])->count();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getResults(?User $user = NULL): object
|
public function getResults(?User $user = null): object
|
||||||
{
|
{
|
||||||
$ctx = DatabaseConnection::i()->getContext();
|
$ctx = DatabaseConnection::i()->getContext();
|
||||||
$voted = NULL;
|
$voted = null;
|
||||||
if(!is_null($user))
|
if (!is_null($user)) {
|
||||||
$voted = $this->getUserVote($user);
|
$voted = $this->getUserVote($user);
|
||||||
|
}
|
||||||
|
|
||||||
$result = (object) [];
|
$result = (object) [];
|
||||||
$result->totalVotes = $this->getVoterCount();
|
$result->totalVotes = $this->getVoterCount();
|
||||||
|
|
||||||
$unsOptions = [];
|
$unsOptions = [];
|
||||||
foreach($this->getOptions() as $id => $title) {
|
foreach ($this->getOptions() as $id => $title) {
|
||||||
$option = (object) [];
|
$option = (object) [];
|
||||||
$option->id = $id;
|
$option->id = $id;
|
||||||
$option->name = $title;
|
$option->name = $title;
|
||||||
|
|
||||||
$option->votes = $this->getVoterCount($id);
|
$option->votes = $this->getVoterCount($id);
|
||||||
$option->pct = $result->totalVotes == 0 ? 0 : min(100, floor(($option->votes / $result->totalVotes) * 100));
|
$option->pct = $result->totalVotes == 0 ? 0 : min(100, floor(($option->votes / $result->totalVotes) * 100));
|
||||||
$option->voters = $this->getVoters($id, 1, 10);
|
$option->voters = $this->getVoters($id, 1, 10);
|
||||||
if(!$user || !$voted)
|
if (!$user || !$voted) {
|
||||||
$option->voted = NULL;
|
$option->voted = null;
|
||||||
else
|
} else {
|
||||||
$option->voted = in_array([$id, $title], $voted);
|
$option->voted = in_array([$id, $title], $voted);
|
||||||
|
}
|
||||||
|
|
||||||
$unsOptions[$id] = $option;
|
$unsOptions[$id] = $option;
|
||||||
}
|
}
|
||||||
|
|
||||||
$optionsC = sizeof($unsOptions);
|
$optionsC = sizeof($unsOptions);
|
||||||
$sOptions = $unsOptions;
|
$sOptions = $unsOptions;
|
||||||
usort($sOptions, function($a, $b) { return $a->votes <=> $b->votes; });
|
usort($sOptions, function ($a, $b) { return $a->votes <=> $b->votes; });
|
||||||
for($i = 0; $i < $optionsC; $i++)
|
for ($i = 0; $i < $optionsC; $i++) {
|
||||||
$unsOptions[$id]->rate = $optionsC - $i - 1;
|
$unsOptions[$id]->rate = $optionsC - $i - 1;
|
||||||
|
}
|
||||||
|
|
||||||
$result->options = array_values($unsOptions);
|
$result->options = array_values($unsOptions);
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAnonymous(): bool
|
public function isAnonymous(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->is_anonymous;
|
return (bool) $this->getRecord()->is_anonymous;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isMultipleChoice(): bool
|
public function isMultipleChoice(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->allows_multiple;
|
return (bool) $this->getRecord()->allows_multiple;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isRevotable(): bool
|
public function isRevotable(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->can_revote;
|
return (bool) $this->getRecord()->can_revote;
|
||||||
}
|
}
|
||||||
|
|
||||||
function endsAt(): ?DateTime
|
public function endsAt(): ?DateTime
|
||||||
{
|
{
|
||||||
if(!$this->getRecord()->until)
|
if (!$this->getRecord()->until) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return new DateTime($this->getRecord()->until);
|
return new DateTime($this->getRecord()->until);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasEnded(): bool
|
public function hasEnded(): bool
|
||||||
{
|
{
|
||||||
if($this->getRecord()->ended)
|
if ($this->getRecord()->ended) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
if(!is_null($this->getRecord()->until))
|
|
||||||
|
if (!is_null($this->getRecord()->until)) {
|
||||||
return time() >= $this->getRecord()->until;
|
return time() >= $this->getRecord()->until;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasVoted(User $user): bool
|
public function hasVoted(User $user): bool
|
||||||
{
|
{
|
||||||
return !is_null($this->getUserVote($user));
|
return !is_null($this->getUserVote($user));
|
||||||
}
|
}
|
||||||
|
|
||||||
function canVote(User $user): bool
|
public function canVote(User $user): bool
|
||||||
{
|
{
|
||||||
return !$this->hasEnded() && !$this->hasVoted($user) && !is_null($this->getAttachedPost()) && $this->getAttachedPost()->getSuggestionType() == 0;
|
return !$this->hasEnded() && !$this->hasVoted($user) && !is_null($this->getAttachedPost()) && $this->getAttachedPost()->getSuggestionType() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function vote(User $user, array $optionIds): void
|
public function vote(User $user, array $optionIds): void
|
||||||
{
|
{
|
||||||
if($this->hasEnded())
|
if ($this->hasEnded()) {
|
||||||
throw new PollLockedException;
|
throw new PollLockedException();
|
||||||
|
}
|
||||||
if($this->hasVoted($user))
|
|
||||||
throw new AlreadyVotedException;
|
if ($this->hasVoted($user)) {
|
||||||
|
throw new AlreadyVotedException();
|
||||||
$optionIds = array_map(function($x) { return (int) $x; }, array_unique($optionIds));
|
}
|
||||||
|
|
||||||
|
$optionIds = array_map(function ($x) { return (int) $x; }, array_unique($optionIds));
|
||||||
$validOpts = array_keys($this->getOptions());
|
$validOpts = array_keys($this->getOptions());
|
||||||
if(empty($optionIds) || (sizeof($optionIds) > 1 && !$this->isMultipleChoice()))
|
if (empty($optionIds) || (sizeof($optionIds) > 1 && !$this->isMultipleChoice())) {
|
||||||
throw new UnexpectedValueException;
|
throw new UnexpectedValueException();
|
||||||
|
}
|
||||||
if(sizeof(array_diff($optionIds, $validOpts)) > 0)
|
|
||||||
throw new InvalidOptionException;
|
if (sizeof(array_diff($optionIds, $validOpts)) > 0) {
|
||||||
|
throw new InvalidOptionException();
|
||||||
foreach($optionIds as $opt) {
|
}
|
||||||
|
|
||||||
|
foreach ($optionIds as $opt) {
|
||||||
DatabaseConnection::i()->getContext()->table("poll_votes")->insert([
|
DatabaseConnection::i()->getContext()->table("poll_votes")->insert([
|
||||||
"user" => $user->getId(),
|
"user" => $user->getId(),
|
||||||
"poll" => $this->getId(),
|
"poll" => $this->getId(),
|
||||||
|
@ -192,64 +216,69 @@ class Poll extends Attachable
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function revokeVote(User $user): void
|
public function revokeVote(User $user): void
|
||||||
{
|
{
|
||||||
if(!$this->isRevotable())
|
if (!$this->isRevotable()) {
|
||||||
throw new PollLockedException;
|
throw new PollLockedException();
|
||||||
|
}
|
||||||
|
|
||||||
$this->getRecord()->related("poll_votes.poll")
|
$this->getRecord()->related("poll_votes.poll")
|
||||||
->where("user", $user->getId())->delete();
|
->where("user", $user->getId())->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setOwner(User $owner): void
|
public function setOwner(User $owner): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("owner", $owner->getId());
|
$this->stateChanges("owner", $owner->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
function setEndDate(int $timestamp): void
|
public function setEndDate(int $timestamp): void
|
||||||
{
|
{
|
||||||
if(!is_null($this->getRecord()))
|
if (!is_null($this->getRecord())) {
|
||||||
throw new PollLockedException;
|
throw new PollLockedException();
|
||||||
|
}
|
||||||
|
|
||||||
$this->stateChanges("until", $timestamp);
|
$this->stateChanges("until", $timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setEnded(): void
|
public function setEnded(): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("ended", 1);
|
$this->stateChanges("ended", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setOptions(array $options): void
|
public function setOptions(array $options): void
|
||||||
{
|
{
|
||||||
if(!is_null($this->getRecord()))
|
if (!is_null($this->getRecord())) {
|
||||||
throw new PollLockedException;
|
throw new PollLockedException();
|
||||||
|
}
|
||||||
if(sizeof($options) > ovkGetQuirk("polls.max-opts"))
|
|
||||||
throw new TooMuchOptionsException;
|
if (sizeof($options) > ovkGetQuirk("polls.max-opts")) {
|
||||||
|
throw new TooMuchOptionsException();
|
||||||
|
}
|
||||||
|
|
||||||
$this->choicesToPersist = $options;
|
$this->choicesToPersist = $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setRevotability(bool $canReVote): void
|
public function setRevotability(bool $canReVote): void
|
||||||
{
|
{
|
||||||
if(!is_null($this->getRecord()))
|
if (!is_null($this->getRecord())) {
|
||||||
throw new PollLockedException;
|
throw new PollLockedException();
|
||||||
|
}
|
||||||
|
|
||||||
$this->stateChanges("can_revote", $canReVote);
|
$this->stateChanges("can_revote", $canReVote);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAnonymity(bool $anonymous): void
|
public function setAnonymity(bool $anonymous): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("is_anonymous", $anonymous);
|
$this->stateChanges("is_anonymous", $anonymous);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setMultipleChoice(bool $mc): void
|
public function setMultipleChoice(bool $mc): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("allows_multiple", $mc);
|
$this->stateChanges("allows_multiple", $mc);
|
||||||
}
|
}
|
||||||
|
|
||||||
function importXML(User $owner, string $xml): void
|
public function importXML(User $owner, string $xml): void
|
||||||
{
|
{
|
||||||
$xml = simplexml_load_string($xml);
|
$xml = simplexml_load_string($xml);
|
||||||
$this->setOwner($owner);
|
$this->setOwner($owner);
|
||||||
|
@ -257,46 +286,50 @@ class Poll extends Attachable
|
||||||
$this->setMultipleChoice(($xml["multiple"] ?? "no") == "yes");
|
$this->setMultipleChoice(($xml["multiple"] ?? "no") == "yes");
|
||||||
$this->setAnonymity(($xml["anonymous"] ?? "no") == "yes");
|
$this->setAnonymity(($xml["anonymous"] ?? "no") == "yes");
|
||||||
$this->setRevotability(($xml["locked"] ?? "no") == "no");
|
$this->setRevotability(($xml["locked"] ?? "no") == "no");
|
||||||
if(ctype_digit((string) ($xml["duration"] ?? "")))
|
if (ctype_digit((string) ($xml["duration"] ?? ""))) {
|
||||||
$this->setEndDate(time() + ((86400 * (int) $xml["duration"])));
|
$this->setEndDate(time() + ((86400 * (int) $xml["duration"])));
|
||||||
|
}
|
||||||
|
|
||||||
$options = [];
|
$options = [];
|
||||||
foreach($xml->options->option as $opt)
|
foreach ($xml->options->option as $opt) {
|
||||||
$options[] = (string) $opt;
|
$options[] = (string) $opt;
|
||||||
|
}
|
||||||
if(empty($options))
|
|
||||||
throw new UnexpectedValueException;
|
if (empty($options)) {
|
||||||
|
throw new UnexpectedValueException();
|
||||||
|
}
|
||||||
|
|
||||||
$this->setOptions($options);
|
$this->setOptions($options);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function import(User $owner, string $xml): Poll
|
public static function import(User $owner, string $xml): Poll
|
||||||
{
|
{
|
||||||
$poll = new Poll;
|
$poll = new Poll();
|
||||||
$poll->importXML($owner, $xml);
|
$poll->importXML($owner, $xml);
|
||||||
$poll->save();
|
$poll->save();
|
||||||
|
|
||||||
return $poll;
|
return $poll;
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBeViewedBy(?User $user = NULL): bool
|
public function canBeViewedBy(?User $user = null): bool
|
||||||
{
|
{
|
||||||
# waiting for #935 :(
|
# waiting for #935 :(
|
||||||
/*if(!is_null($this->getAttachedPost())) {
|
/*if(!is_null($this->getAttachedPost())) {
|
||||||
return $this->getAttachedPost()->canBeViewedBy($user);
|
return $this->getAttachedPost()->canBeViewedBy($user);
|
||||||
} else {*/
|
} else {*/
|
||||||
return true;
|
return true;
|
||||||
#}
|
#}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function save(?bool $log = false): void
|
public function save(?bool $log = false): void
|
||||||
{
|
{
|
||||||
if(empty($this->choicesToPersist))
|
if (empty($this->choicesToPersist)) {
|
||||||
throw new InvalidStateException;
|
throw new InvalidStateException();
|
||||||
|
}
|
||||||
|
|
||||||
parent::save($log);
|
parent::save($log);
|
||||||
foreach($this->choicesToPersist as $option) {
|
foreach ($this->choicesToPersist as $option) {
|
||||||
DatabaseConnection::i()->getContext()->table("poll_options")->insert([
|
DatabaseConnection::i()->getContext()->table("poll_options")->insert([
|
||||||
"poll" => $this->getId(),
|
"poll" => $this->getId(),
|
||||||
"name" => $option,
|
"name" => $option,
|
||||||
|
@ -304,16 +337,18 @@ class Poll extends Attachable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAttachedPost()
|
public function getAttachedPost()
|
||||||
{
|
{
|
||||||
$post = DatabaseConnection::i()->getContext()->table("attachments")
|
$post = DatabaseConnection::i()->getContext()->table("attachments")
|
||||||
->where(
|
->where(
|
||||||
["attachable_type" => static::class,
|
["attachable_type" => static::class,
|
||||||
"attachable_id" => $this->getId()])->fetch();
|
"attachable_id" => $this->getId()]
|
||||||
|
)->fetch();
|
||||||
|
|
||||||
if(!is_null($post->target_id))
|
if (!is_null($post->target_id)) {
|
||||||
return (new Posts)->get($post->target_id);
|
return (new Posts())->get($post->target_id);
|
||||||
else
|
} else {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use Chandler\Database\DatabaseConnection as DB;
|
use Chandler\Database\DatabaseConnection as DB;
|
||||||
use openvk\Web\Models\Repositories\{Clubs, Users};
|
use openvk\Web\Models\Repositories\{Clubs, Users};
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
|
@ -7,6 +11,7 @@ use openvk\Web\Models\Entities\Notifications\LikeNotification;
|
||||||
|
|
||||||
class Post extends Postable
|
class Post extends Postable
|
||||||
{
|
{
|
||||||
|
use Traits\TRichText;
|
||||||
protected $tableName = "posts";
|
protected $tableName = "posts";
|
||||||
protected $upperNodeReferenceColumnName = "wall";
|
protected $upperNodeReferenceColumnName = "wall";
|
||||||
|
|
||||||
|
@ -18,54 +23,60 @@ class Post extends Postable
|
||||||
"target" => $this->getRecord()->id,
|
"target" => $this->getRecord()->id,
|
||||||
];
|
];
|
||||||
|
|
||||||
if((sizeof(DB::i()->getContext()->table("likes")->where($searchData)) > 0) !== $liked) {
|
if ((sizeof(DB::i()->getContext()->table("likes")->where($searchData)) > 0) !== $liked) {
|
||||||
if($this->getOwner(false)->getId() !== $user->getId() && !($this->getOwner() instanceof Club) && !$this instanceof Comment)
|
if ($this->getOwner(false)->getId() !== $user->getId() && !($this->getOwner() instanceof Club) && !$this instanceof Comment) {
|
||||||
(new LikeNotification($this->getOwner(false), $this, $user))->emit();
|
(new LikeNotification($this->getOwner(false), $this, $user))->emit();
|
||||||
|
}
|
||||||
|
|
||||||
parent::setLike($liked, $user);
|
parent::setLike($liked, $user);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($depth < ovkGetQuirk("wall.repost-liking-recursion-limit"))
|
if ($depth < ovkGetQuirk("wall.repost-liking-recursion-limit")) {
|
||||||
foreach($this->getChildren() as $attachment)
|
foreach ($this->getChildren() as $attachment) {
|
||||||
if($attachment instanceof Post)
|
if ($attachment instanceof Post) {
|
||||||
$attachment->setLikeRecursively($liked, $user, $depth + 1);
|
$attachment->setLikeRecursively($liked, $user, $depth + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* May return fake owner (group), if flags are [1, (*)]
|
* May return fake owner (group), if flags are [1, (*)]
|
||||||
*
|
*
|
||||||
* @param bool $honourFlags - check flags
|
* @param bool $honourFlags - check flags
|
||||||
*/
|
*/
|
||||||
function getOwner(bool $honourFlags = true, bool $real = false): RowModel
|
public function getOwner(bool $honourFlags = true, bool $real = false): RowModel
|
||||||
{
|
{
|
||||||
if($honourFlags && $this->isPostedOnBehalfOfGroup()) {
|
if ($honourFlags && $this->isPostedOnBehalfOfGroup()) {
|
||||||
if($this->getRecord()->wall < 0)
|
if ($this->getRecord()->wall < 0) {
|
||||||
return (new Clubs)->get(abs($this->getRecord()->wall));
|
return (new Clubs())->get(abs($this->getRecord()->wall));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::getOwner($real);
|
return parent::getOwner($real);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPrettyId(): string
|
public function getPrettyId(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->wall . "_" . $this->getVirtualId();
|
return $this->getRecord()->wall . "_" . $this->getVirtualId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTargetWall(): int
|
public function getTargetWall(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->wall;
|
return $this->getRecord()->wall;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getWallOwner()
|
public function getWallOwner()
|
||||||
{
|
{
|
||||||
$w = $this->getRecord()->wall;
|
$w = $this->getRecord()->wall;
|
||||||
if($w < 0)
|
if ($w < 0) {
|
||||||
return (new Clubs)->get(abs($w));
|
return (new Clubs())->get(abs($w));
|
||||||
|
}
|
||||||
|
|
||||||
return (new Users)->get($w);
|
return (new Users())->get($w);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRepostCount(): int
|
public function getRepostCount(): int
|
||||||
{
|
{
|
||||||
return sizeof(
|
return sizeof(
|
||||||
$this->getRecord()
|
$this->getRecord()
|
||||||
|
@ -73,95 +84,97 @@ class Post extends Postable
|
||||||
->where("attachable_type", get_class($this))
|
->where("attachable_type", get_class($this))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPinned(): bool
|
public function isPinned(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->pinned;
|
return (bool) $this->getRecord()->pinned;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasSource(): bool
|
public function hasSource(): bool
|
||||||
{
|
{
|
||||||
return $this->getRecord()->source != NULL;
|
return $this->getRecord()->source != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSource(bool $format = false)
|
public function getSource(bool $format = false)
|
||||||
{
|
{
|
||||||
$orig_source = $this->getRecord()->source;
|
$orig_source = $this->getRecord()->source;
|
||||||
if(!str_contains($orig_source, "https://") && !str_contains($orig_source, "http://"))
|
if (!str_contains($orig_source, "https://") && !str_contains($orig_source, "http://")) {
|
||||||
$orig_source = "https://" . $orig_source;
|
$orig_source = "https://" . $orig_source;
|
||||||
|
}
|
||||||
|
|
||||||
if(!$format)
|
if (!$format) {
|
||||||
return $orig_source;
|
return $orig_source;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->formatLinks($orig_source);
|
return $this->formatLinks($orig_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSource(string $source)
|
public function setSource(string $source)
|
||||||
{
|
{
|
||||||
$result = check_copyright_link($source);
|
$result = check_copyright_link($source);
|
||||||
|
|
||||||
$this->stateChanges("source", $source);
|
$this->stateChanges("source", $source);
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetSource()
|
public function resetSource()
|
||||||
{
|
{
|
||||||
$this->stateChanges("source", NULL);
|
$this->stateChanges("source", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVkApiCopyright(): object
|
public function getVkApiCopyright(): object
|
||||||
{
|
{
|
||||||
return (object)[
|
return (object) [
|
||||||
'id' => 0,
|
'id' => 0,
|
||||||
'link' => $this->getSource(false),
|
'link' => $this->getSource(false),
|
||||||
'name' => $this->getSource(false),
|
'name' => $this->getSource(false),
|
||||||
'type' => 'link',
|
'type' => 'link',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAd(): bool
|
public function isAd(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->ad;
|
return (bool) $this->getRecord()->ad;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPostedOnBehalfOfGroup(): bool
|
public function isPostedOnBehalfOfGroup(): bool
|
||||||
{
|
{
|
||||||
return ($this->getRecord()->flags & 0b10000000) > 0;
|
return ($this->getRecord()->flags & 0b10000000) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSigned(): bool
|
public function isSigned(): bool
|
||||||
{
|
{
|
||||||
return ($this->getRecord()->flags & 0b01000000) > 0;
|
return ($this->getRecord()->flags & 0b01000000) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDeactivationMessage(): bool
|
public function isDeactivationMessage(): bool
|
||||||
{
|
{
|
||||||
return (($this->getRecord()->flags & 0b00100000) > 0) && ($this->getRecord()->owner > 0);
|
return (($this->getRecord()->flags & 0b00100000) > 0) && ($this->getRecord()->owner > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isUpdateAvatarMessage(): bool
|
public function isUpdateAvatarMessage(): bool
|
||||||
{
|
{
|
||||||
return (($this->getRecord()->flags & 0b00010000) > 0) && ($this->getRecord()->owner > 0);
|
return (($this->getRecord()->flags & 0b00010000) > 0) && ($this->getRecord()->owner > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isExplicit(): bool
|
public function isExplicit(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->nsfw;
|
return (bool) $this->getRecord()->nsfw;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDeleted(): bool
|
public function isDeleted(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->deleted;
|
return (bool) $this->getRecord()->deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOwnerPost(): int
|
public function getOwnerPost(): int
|
||||||
{
|
{
|
||||||
return $this->getOwner(false)->getId();
|
return $this->getOwner(false)->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPlatform(bool $forAPI = false): ?string
|
public function getPlatform(bool $forAPI = false): ?string
|
||||||
{
|
{
|
||||||
$platform = $this->getRecord()->api_source_name;
|
$platform = $this->getRecord()->api_source_name;
|
||||||
if($forAPI) {
|
if ($forAPI) {
|
||||||
switch ($platform) {
|
switch ($platform) {
|
||||||
case 'openvk_refresh_android':
|
case 'openvk_refresh_android':
|
||||||
case 'openvk_legacy_android':
|
case 'openvk_legacy_android':
|
||||||
|
@ -176,16 +189,16 @@ class Post extends Postable
|
||||||
case 'windows_phone':
|
case 'windows_phone':
|
||||||
return 'wphone';
|
return 'wphone';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'vika_touch': // кика хохотач ахахахаххахахахахах
|
case 'vika_touch': // кика хохотач ахахахаххахахахахах
|
||||||
case 'vk4me':
|
case 'vk4me':
|
||||||
return 'mobile';
|
return 'mobile';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NULL:
|
case null:
|
||||||
return NULL;
|
return null;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 'api';
|
return 'api';
|
||||||
break;
|
break;
|
||||||
|
@ -195,17 +208,17 @@ class Post extends Postable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPlatformDetails(): array
|
public function getPlatformDetails(): array
|
||||||
{
|
{
|
||||||
$clients = simplexml_load_file(OPENVK_ROOT . "/data/clients.xml");
|
$clients = simplexml_load_file(OPENVK_ROOT . "/data/clients.xml");
|
||||||
|
|
||||||
foreach($clients as $client) {
|
foreach ($clients as $client) {
|
||||||
if($client['tag'] == $this->getPlatform()) {
|
if ($client['tag'] == $this->getPlatform()) {
|
||||||
return [
|
return [
|
||||||
"tag" => $client['tag'],
|
"tag" => $client['tag'],
|
||||||
"name" => $client['name'],
|
"name" => $client['name'],
|
||||||
"url" => $client['url'],
|
"url" => $client['url'],
|
||||||
"img" => $client['img']
|
"img" => $client['img'],
|
||||||
];
|
];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -213,38 +226,40 @@ class Post extends Postable
|
||||||
|
|
||||||
return [
|
return [
|
||||||
"tag" => $this->getPlatform(),
|
"tag" => $this->getPlatform(),
|
||||||
"name" => NULL,
|
"name" => null,
|
||||||
"url" => NULL,
|
"url" => null,
|
||||||
"img" => NULL
|
"img" => null,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPostSourceInfo(): array
|
public function getPostSourceInfo(): array
|
||||||
{
|
{
|
||||||
$post_source = ["type" => "vk"];
|
$post_source = ["type" => "vk"];
|
||||||
if($this->getPlatform(true) !== NULL) {
|
if ($this->getPlatform(true) !== null) {
|
||||||
$post_source = [
|
$post_source = [
|
||||||
"type" => "api",
|
"type" => "api",
|
||||||
"platform" => $this->getPlatform(true)
|
"platform" => $this->getPlatform(true),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->isUpdateAvatarMessage())
|
if ($this->isUpdateAvatarMessage()) {
|
||||||
$post_source['data'] = 'profile_photo';
|
$post_source['data'] = 'profile_photo';
|
||||||
|
}
|
||||||
|
|
||||||
return $post_source;
|
return $post_source;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVkApiType(): string
|
public function getVkApiType(): string
|
||||||
{
|
{
|
||||||
$type = 'post';
|
$type = 'post';
|
||||||
if($this->getSuggestionType() != 0)
|
if ($this->getSuggestionType() != 0) {
|
||||||
$type = 'suggest';
|
$type = 'suggest';
|
||||||
|
}
|
||||||
|
|
||||||
return $type;
|
return $type;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pin(): void
|
public function pin(): void
|
||||||
{
|
{
|
||||||
DB::i()
|
DB::i()
|
||||||
->getContext()
|
->getContext()
|
||||||
|
@ -254,98 +269,106 @@ class Post extends Postable
|
||||||
"pinned" => true,
|
"pinned" => true,
|
||||||
])
|
])
|
||||||
->update(["pinned" => false]);
|
->update(["pinned" => false]);
|
||||||
|
|
||||||
$this->stateChanges("pinned", true);
|
$this->stateChanges("pinned", true);
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
function unpin(): void
|
public function unpin(): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("pinned", false);
|
$this->stateChanges("pinned", false);
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBePinnedBy(User $user = NULL): bool
|
|
||||||
{
|
|
||||||
if(!$user)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if($this->getTargetWall() < 0)
|
public function canBePinnedBy(User $user = null): bool
|
||||||
return (new Clubs)->get(abs($this->getTargetWall()))->canBeModifiedBy($user);
|
{
|
||||||
|
if (!$user) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->getTargetWall() < 0) {
|
||||||
|
return (new Clubs())->get(abs($this->getTargetWall()))->canBeModifiedBy($user);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->getTargetWall() === $user->getId();
|
return $this->getTargetWall() === $user->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBeDeletedBy(User $user = NULL): bool
|
public function canBeDeletedBy(User $user = null): bool
|
||||||
{
|
{
|
||||||
if(!$user)
|
if (!$user) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
if($this->getTargetWall() < 0 && !$this->getWallOwner()->canBeModifiedBy($user) && $this->getWallOwner()->getWallType() != 1 && $this->getSuggestionType() == 0)
|
|
||||||
|
if ($this->getTargetWall() < 0 && !$this->getWallOwner()->canBeModifiedBy($user) && $this->getWallOwner()->getWallType() != 1 && $this->getSuggestionType() == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->getOwnerPost() === $user->getId() || $this->canBePinnedBy($user);
|
return $this->getOwnerPost() === $user->getId() || $this->canBePinnedBy($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setContent(string $content): void
|
public function setContent(string $content): void
|
||||||
{
|
{
|
||||||
if(ctype_space($content))
|
if (ctype_space($content)) {
|
||||||
throw new \LengthException("Content length must be at least 1 character (not counting whitespaces).");
|
throw new \LengthException("Content length must be at least 1 character (not counting whitespaces).");
|
||||||
else if(iconv_strlen($content) > OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["maxSize"])
|
} elseif (iconv_strlen($content) > OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["maxSize"]) {
|
||||||
throw new \LengthException("Content is too large.");
|
throw new \LengthException("Content is too large.");
|
||||||
|
}
|
||||||
|
|
||||||
$this->stateChanges("content", $content);
|
$this->stateChanges("content", $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleLike(User $user): bool
|
public function toggleLike(User $user): bool
|
||||||
{
|
{
|
||||||
$liked = parent::toggleLike($user);
|
$liked = parent::toggleLike($user);
|
||||||
|
|
||||||
if(!$user->isPrivateLikes() && $this->getOwner(false)->getId() !== $user->getId() && !($this->getOwner() instanceof Club) && !$this instanceof Comment)
|
if (!$user->isPrivateLikes() && $this->getOwner(false)->getId() !== $user->getId() && !($this->getOwner() instanceof Club) && !$this instanceof Comment) {
|
||||||
(new LikeNotification($this->getOwner(false), $this, $user))->emit();
|
(new LikeNotification($this->getOwner(false), $this, $user))->emit();
|
||||||
|
}
|
||||||
|
|
||||||
foreach($this->getChildren() as $attachment)
|
foreach ($this->getChildren() as $attachment) {
|
||||||
if($attachment instanceof Post)
|
if ($attachment instanceof Post) {
|
||||||
$attachment->setLikeRecursively($liked, $user, 2);
|
$attachment->setLikeRecursively($liked, $user, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $liked;
|
return $liked;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLike(bool $liked, User $user): void
|
public function setLike(bool $liked, User $user): void
|
||||||
{
|
{
|
||||||
$this->setLikeRecursively($liked, $user, 1);
|
$this->setLikeRecursively($liked, $user, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function deletePost(): void
|
public function deletePost(): void
|
||||||
{
|
{
|
||||||
$this->setDeleted(1);
|
$this->setDeleted(1);
|
||||||
$this->unwire();
|
$this->unwire();
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBeViewedBy(?User $user = NULL): bool
|
public function canBeViewedBy(?User $user = null): bool
|
||||||
{
|
{
|
||||||
if($this->isDeleted()) {
|
if ($this->isDeleted()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->getWallOwner()->canBeViewedBy($user);
|
return $this->getWallOwner()->canBeViewedBy($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSuggestionType()
|
public function getSuggestionType()
|
||||||
{
|
{
|
||||||
return $this->getRecord()->suggested;
|
return $this->getRecord()->suggested;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPageURL(): string
|
public function getPageURL(): string
|
||||||
{
|
{
|
||||||
return "/wall".$this->getPrettyId();
|
return "/wall" . $this->getPrettyId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function toNotifApiStruct()
|
public function toNotifApiStruct()
|
||||||
{
|
{
|
||||||
$res = (object)[];
|
$res = (object) [];
|
||||||
|
|
||||||
$res->id = $this->getVirtualId();
|
$res->id = $this->getVirtualId();
|
||||||
$res->to_id = $this->getOwner() instanceof Club ? $this->getOwner()->getId() * -1 : $this->getOwner()->getId();
|
$res->to_id = $this->getOwner() instanceof Club ? $this->getOwner()->getId() * -1 : $this->getOwner()->getId();
|
||||||
$res->from_id = $res->to_id;
|
$res->from_id = $res->to_id;
|
||||||
|
@ -353,97 +376,105 @@ class Post extends Postable
|
||||||
$res->text = $this->getText(false);
|
$res->text = $this->getText(false);
|
||||||
$res->attachments = []; # todo
|
$res->attachments = []; # todo
|
||||||
|
|
||||||
$res->copy_owner_id = NULL; # todo
|
$res->copy_owner_id = null; # todo
|
||||||
$res->copy_post_id = NULL; # todo
|
$res->copy_post_id = null; # todo
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBeEditedBy(?User $user = NULL): bool
|
public function canBeEditedBy(?User $user = null): bool
|
||||||
{
|
{
|
||||||
if(!$user)
|
if (!$user) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if($this->isDeactivationMessage() || $this->isUpdateAvatarMessage())
|
if ($this->isDeactivationMessage() || $this->isUpdateAvatarMessage()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if($this->getTargetWall() > 0)
|
if ($this->getTargetWall() > 0) {
|
||||||
return $this->getPublicationTime()->timestamp() + WEEK > time() && $user->getId() == $this->getOwner(false)->getId();
|
return $this->getPublicationTime()->timestamp() + WEEK > time() && $user->getId() == $this->getOwner(false)->getId();
|
||||||
else {
|
} else {
|
||||||
if($this->isPostedOnBehalfOfGroup())
|
if ($this->isPostedOnBehalfOfGroup()) {
|
||||||
return $this->getWallOwner()->canBeModifiedBy($user);
|
return $this->getWallOwner()->canBeModifiedBy($user);
|
||||||
else
|
} else {
|
||||||
return $user->getId() == $this->getOwner(false)->getId();
|
return $user->getId() == $this->getOwner(false)->getId();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $user->getId() == $this->getOwner(false)->getId();
|
return $user->getId() == $this->getOwner(false)->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function toRss(): \Bhaktaraz\RSSGenerator\Item
|
public function toRss(): \Bhaktaraz\RSSGenerator\Item
|
||||||
{
|
{
|
||||||
$domain = ovk_scheme(true).$_SERVER["HTTP_HOST"];
|
$domain = ovk_scheme(true) . $_SERVER["HTTP_HOST"];
|
||||||
$description = $this->getText(false);
|
$description = $this->getText(false);
|
||||||
$title = str_replace("\n", "", ovk_proc_strtr($description, 79));
|
$title = str_replace("\n", "", ovk_proc_strtr($description, 79));
|
||||||
$description_html = $description;
|
$description_html = $description;
|
||||||
$url = $domain."/wall".$this->getPrettyId();
|
$url = $domain . "/wall" . $this->getPrettyId();
|
||||||
|
|
||||||
if($this->isUpdateAvatarMessage())
|
if ($this->isUpdateAvatarMessage()) {
|
||||||
$title = tr('upd_in_general');
|
$title = tr('upd_in_general');
|
||||||
if($this->isDeactivationMessage())
|
}
|
||||||
|
if ($this->isDeactivationMessage()) {
|
||||||
$title = tr('post_deact_in_general');
|
$title = tr('post_deact_in_general');
|
||||||
|
}
|
||||||
|
|
||||||
$author = $this->getOwner();
|
$author = $this->getOwner();
|
||||||
$target_wall = $this->getWallOwner();
|
$target_wall = $this->getWallOwner();
|
||||||
$author_name = escape_html($author->getCanonicalName());
|
$author_name = escape_html($author->getCanonicalName());
|
||||||
if($this->isExplicit())
|
if ($this->isExplicit()) {
|
||||||
$title = 'NSFW: ' . $title;
|
$title = 'NSFW: ' . $title;
|
||||||
|
}
|
||||||
|
|
||||||
foreach($this->getChildren() as $child) {
|
foreach ($this->getChildren() as $child) {
|
||||||
if($child instanceof Photo) {
|
if ($child instanceof Photo) {
|
||||||
$child_page = $domain.$child->getPageURL();
|
$child_page = $domain . $child->getPageURL();
|
||||||
$child_url = $child->getURL();
|
$child_url = $child->getURL();
|
||||||
$description_html .= "<br /><a href='$child_page'><img src='$child_url'></a><br />";
|
$description_html .= "<br /><a href='$child_page'><img src='$child_url'></a><br />";
|
||||||
} elseif($child instanceof Video) {
|
} elseif ($child instanceof Video) {
|
||||||
$child_page = $domain.'/video'.$child->getPrettyId();
|
$child_page = $domain . '/video' . $child->getPrettyId();
|
||||||
|
|
||||||
if($child->getType() != 1) {
|
if ($child->getType() != 1) {
|
||||||
$description_html .= "".
|
$description_html .= "" .
|
||||||
"<br />".
|
"<br />" .
|
||||||
"<video width=\"320\" height=\"240\" controls><source src=\"".$child->getURL()."\" type=\"video/mp4\"></video><br />".
|
"<video width=\"320\" height=\"240\" controls><source src=\"" . $child->getURL() . "\" type=\"video/mp4\"></video><br />" .
|
||||||
"<b>".escape_html($child->getName())."</b><br />";
|
"<b>" . escape_html($child->getName()) . "</b><br />";
|
||||||
} else {
|
} else {
|
||||||
$description_html .= "".
|
$description_html .= "" .
|
||||||
"<br />".
|
"<br />" .
|
||||||
"<a href=\"".$child->getVideoDriver()->getURL()."\"><b>".escape_html($child->getName())."</b></a><br />";
|
"<a href=\"" . $child->getVideoDriver()->getURL() . "\"><b>" . escape_html($child->getName()) . "</b></a><br />";
|
||||||
}
|
}
|
||||||
} elseif($child instanceof Audio) {
|
} elseif ($child instanceof Audio) {
|
||||||
if(!$child->isWithdrawn()) {
|
if (!$child->isWithdrawn()) {
|
||||||
$description_html .= "<br />"
|
$description_html .= "<br />"
|
||||||
."<b>".escape_html($child->getName())."</b>:"
|
. "<b>" . escape_html($child->getName()) . "</b>:"
|
||||||
."<br />"
|
. "<br />"
|
||||||
."<audio controls>"
|
. "<audio controls>"
|
||||||
."<source src=\"".$child->getOriginalURL()."\" type=\"audio/mpeg\"></audio>"
|
. "<source src=\"" . $child->getOriginalURL() . "\" type=\"audio/mpeg\"></audio>"
|
||||||
."<br />";
|
. "<br />";
|
||||||
}
|
}
|
||||||
} elseif($child instanceof Poll) {
|
} elseif ($child instanceof Poll) {
|
||||||
$description_html .= "<br />".tr('poll').": ".escape_html($child->getTitle());
|
$description_html .= "<br />" . tr('poll') . ": " . escape_html($child->getTitle());
|
||||||
} elseif($child instanceof Note) {
|
} elseif ($child instanceof Note) {
|
||||||
$description_html .= "<br />".tr('note').": ".escape_html($child->getName());
|
$description_html .= "<br />" . tr('note') . ": " . escape_html($child->getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$description_html .= "<br />".tr('author').": <img width='15px' src='".$author->getAvatarURL()."'><a href='".$author->getURL()."'>" . $author_name . "</a>";
|
$description_html .= "<br />" . tr('author') . ": <img width='15px' src='" . $author->getAvatarURL() . "'><a href='" . $author->getURL() . "'>" . $author_name . "</a>";
|
||||||
|
|
||||||
if($target_wall->getRealId() != $author->getRealId())
|
if ($target_wall->getRealId() != $author->getRealId()) {
|
||||||
$description_html .= "<br />".tr('on_wall').": <img width='15px' src='".$target_wall->getAvatarURL()."'><a href='".$target_wall->getURL()."'>" . escape_html($target_wall->getCanonicalName()) . "</a>";
|
$description_html .= "<br />" . tr('on_wall') . ": <img width='15px' src='" . $target_wall->getAvatarURL() . "'><a href='" . $target_wall->getURL() . "'>" . escape_html($target_wall->getCanonicalName()) . "</a>";
|
||||||
|
|
||||||
if($this->isSigned()) {
|
|
||||||
$signer = $this->getOwner(false);
|
|
||||||
$description_html .= "<br />".tr('sign_short').": <img width='15px' src='".$signer->getAvatarURL()."'><a href='".$signer->getURL()."'>" . escape_html($signer->getCanonicalName()) . "</a>";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->hasSource())
|
if ($this->isSigned()) {
|
||||||
$description_html .= "<br />".tr('source').": ".escape_html($this->getSource());
|
$signer = $this->getOwner(false);
|
||||||
|
$description_html .= "<br />" . tr('sign_short') . ": <img width='15px' src='" . $signer->getAvatarURL() . "'><a href='" . $signer->getURL() . "'>" . escape_html($signer->getCanonicalName()) . "</a>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->hasSource()) {
|
||||||
|
$description_html .= "<br />" . tr('source') . ": " . escape_html($this->getSource());
|
||||||
|
}
|
||||||
|
|
||||||
$item = new \Bhaktaraz\RSSGenerator\Item();
|
$item = new \Bhaktaraz\RSSGenerator\Item();
|
||||||
$item->title($title)
|
$item->title($title)
|
||||||
|
@ -456,39 +487,41 @@ class Post extends Postable
|
||||||
return $item;
|
return $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGeo(): ?object
|
public function getGeo(): ?object
|
||||||
{
|
{
|
||||||
if (!$this->getRecord()->geo) return NULL;
|
if (!$this->getRecord()->geo) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (object) json_decode($this->getRecord()->geo, true, JSON_UNESCAPED_UNICODE);
|
return (object) json_decode($this->getRecord()->geo, true, JSON_UNESCAPED_UNICODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setGeo($encoded_object): void
|
public function setGeo($encoded_object): void
|
||||||
{
|
{
|
||||||
$final_geo = $encoded_object['name'];
|
$final_geo = $encoded_object['name'];
|
||||||
$neutral_names = ["Россия", "Russia", "Росія", "Россія", "Украина", "Ukraine", "Україна", "Украіна"];
|
$neutral_names = ["Россия", "Russia", "Росія", "Россія", "Украина", "Ukraine", "Україна", "Украіна"];
|
||||||
foreach($neutral_names as $name) {
|
foreach ($neutral_names as $name) {
|
||||||
if(str_contains($final_geo, $name.", ")) {
|
if (str_contains($final_geo, $name . ", ")) {
|
||||||
$final_geo = str_replace($name.", ", "", $final_geo);
|
$final_geo = str_replace($name . ", ", "", $final_geo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$encoded_object['name'] = ovk_proc_strtr($final_geo, 255);
|
$encoded_object['name'] = ovk_proc_strtr($final_geo, 255);
|
||||||
$encoded = json_encode($encoded_object);
|
$encoded = json_encode($encoded_object);
|
||||||
$this->stateChanges("geo", $encoded);
|
$this->stateChanges("geo", $encoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLat(): ?float
|
public function getLat(): ?float
|
||||||
{
|
{
|
||||||
return (float) $this->getRecord()->geo_lat ?? NULL;
|
return (float) $this->getRecord()->geo_lat ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLon(): ?float
|
public function getLon(): ?float
|
||||||
{
|
{
|
||||||
return (float) $this->getRecord()->geo_lon ?? NULL;
|
return (float) $this->getRecord()->geo_lon ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVkApiGeo(): object
|
public function getVkApiGeo(): object
|
||||||
{
|
{
|
||||||
return (object) [
|
return (object) [
|
||||||
'type' => 'point',
|
'type' => 'point',
|
||||||
|
@ -496,6 +529,4 @@ class Post extends Postable
|
||||||
'name' => $this->getGeo()->name,
|
'name' => $this->getGeo()->name,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
use Traits\TRichText;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
|
@ -12,83 +16,89 @@ use Nette\Database\Table\Selection;
|
||||||
|
|
||||||
abstract class Postable extends Attachable
|
abstract class Postable extends Attachable
|
||||||
{
|
{
|
||||||
|
use Traits\TAttachmentHost;
|
||||||
|
use Traits\TOwnable;
|
||||||
/**
|
/**
|
||||||
* Column name, that references to an object, that
|
* Column name, that references to an object, that
|
||||||
* is hieararchically higher than this Postable.
|
* is hieararchically higher than this Postable.
|
||||||
*
|
*
|
||||||
* For example: Images belong to User, but Posts belong to Wall.
|
* For example: Images belong to User, but Posts belong to Wall.
|
||||||
* Formally users still own posts, but walls also own posts and they are
|
* Formally users still own posts, but walls also own posts and they are
|
||||||
* their direct parent.
|
* their direct parent.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $upperNodeReferenceColumnName = "owner";
|
protected $upperNodeReferenceColumnName = "owner";
|
||||||
|
|
||||||
private function getTable(): Selection
|
private function getTable(): Selection
|
||||||
{
|
{
|
||||||
return DB::i()->getContext()->table($this->tableName);
|
return DB::i()->getContext()->table($this->tableName);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOwner(bool $real = false): RowModel
|
public function getOwner(bool $real = false): RowModel
|
||||||
{
|
{
|
||||||
$oid = (int) $this->getRecord()->owner;
|
$oid = (int) $this->getRecord()->owner;
|
||||||
if(!$real && $this->isAnonymous())
|
if (!$real && $this->isAnonymous()) {
|
||||||
$oid = (int) OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["account"];
|
$oid = (int) OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["account"];
|
||||||
|
}
|
||||||
|
|
||||||
$oid = abs($oid);
|
$oid = abs($oid);
|
||||||
if($oid > 0)
|
if ($oid > 0) {
|
||||||
return (new Users)->get($oid);
|
return (new Users())->get($oid);
|
||||||
else
|
} else {
|
||||||
return (new Clubs)->get($oid * -1);
|
return (new Clubs())->get($oid * -1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVirtualId(): int
|
public function getVirtualId(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->virtual_id;
|
return $this->getRecord()->virtual_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPrettyId(): string
|
public function getPrettyId(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->owner . "_" . $this->getVirtualId();
|
return $this->getRecord()->owner . "_" . $this->getVirtualId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPublicationTime(): DateTime
|
public function getPublicationTime(): DateTime
|
||||||
{
|
{
|
||||||
return new DateTime($this->getRecord()->created);
|
return new DateTime($this->getRecord()->created);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEditTime(): ?DateTime
|
public function getEditTime(): ?DateTime
|
||||||
{
|
{
|
||||||
$edited = $this->getRecord()->edited;
|
$edited = $this->getRecord()->edited;
|
||||||
if(is_null($edited)) return NULL;
|
if (is_null($edited)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return new DateTime($edited);
|
return new DateTime($edited);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComments(int $page, ?int $perPage = NULL): \Traversable
|
public function getComments(int $page, ?int $perPage = null): \Traversable
|
||||||
{
|
{
|
||||||
return (new Comments)->getCommentsByTarget($this, $page, $perPage);
|
return (new Comments())->getCommentsByTarget($this, $page, $perPage);
|
||||||
}
|
|
||||||
|
|
||||||
function getCommentsCount(): int
|
|
||||||
{
|
|
||||||
return (new Comments)->getCommentsCountByTarget($this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLastComments(int $count): \Traversable
|
public function getCommentsCount(): int
|
||||||
{
|
{
|
||||||
return (new Comments)->getLastCommentsByTarget($this, $count);
|
return (new Comments())->getCommentsCountByTarget($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLikesCount(): int
|
public function getLastComments(int $count): \Traversable
|
||||||
|
{
|
||||||
|
return (new Comments())->getLastCommentsByTarget($this, $count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLikesCount(): int
|
||||||
{
|
{
|
||||||
return sizeof(DB::i()->getContext()->table("likes")->where([
|
return sizeof(DB::i()->getContext()->table("likes")->where([
|
||||||
"model" => static::class,
|
"model" => static::class,
|
||||||
"target" => $this->getRecord()->id,
|
"target" => $this->getRecord()->id,
|
||||||
])->group("origin"));
|
])->group("origin"));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLikers(int $page = 1, ?int $perPage = NULL): \Traversable
|
public function getLikers(int $page = 1, ?int $perPage = null): \Traversable
|
||||||
{
|
{
|
||||||
$perPage ??= OPENVK_DEFAULT_PER_PAGE;
|
$perPage ??= OPENVK_DEFAULT_PER_PAGE;
|
||||||
|
|
||||||
|
@ -96,42 +106,42 @@ abstract class Postable extends Attachable
|
||||||
"model" => static::class,
|
"model" => static::class,
|
||||||
"target" => $this->getRecord()->id,
|
"target" => $this->getRecord()->id,
|
||||||
])->page($page, $perPage);
|
])->page($page, $perPage);
|
||||||
|
|
||||||
foreach($sel as $like) {
|
foreach ($sel as $like) {
|
||||||
$user = (new Users)->get($like->origin);
|
$user = (new Users())->get($like->origin);
|
||||||
if($user->isPrivateLikes() && OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["enable"]) {
|
if ($user->isPrivateLikes() && OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["enable"]) {
|
||||||
$user = (new Users)->get((int) OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["account"]);
|
$user = (new Users())->get((int) OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["account"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
yield $user;
|
yield $user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAccessKey(): string
|
public function getAccessKey(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->access_key;
|
return $this->getRecord()->access_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkAccessKey(?string $access_key): bool
|
public function checkAccessKey(?string $access_key): bool
|
||||||
{
|
{
|
||||||
if($this->getAccessKey() === $access_key) {
|
if ($this->getAccessKey() === $access_key) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !$this->isPrivate();
|
return !$this->isPrivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPrivate(): bool
|
public function isPrivate(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->unlisted;
|
return (bool) $this->getRecord()->unlisted;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAnonymous(): bool
|
public function isAnonymous(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->anonymous;
|
return (bool) $this->getRecord()->anonymous;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleLike(User $user): bool
|
public function toggleLike(User $user): bool
|
||||||
{
|
{
|
||||||
$searchData = [
|
$searchData = [
|
||||||
"origin" => $user->getId(),
|
"origin" => $user->getId(),
|
||||||
|
@ -139,7 +149,7 @@ abstract class Postable extends Attachable
|
||||||
"target" => $this->getRecord()->id,
|
"target" => $this->getRecord()->id,
|
||||||
];
|
];
|
||||||
|
|
||||||
if(sizeof(DB::i()->getContext()->table("likes")->where($searchData)) > 0) {
|
if (sizeof(DB::i()->getContext()->table("likes")->where($searchData)) > 0) {
|
||||||
DB::i()->getContext()->table("likes")->where($searchData)->delete();
|
DB::i()->getContext()->table("likes")->where($searchData)->delete();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -148,7 +158,7 @@ abstract class Postable extends Attachable
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLike(bool $liked, User $user): void
|
public function setLike(bool $liked, User $user): void
|
||||||
{
|
{
|
||||||
$searchData = [
|
$searchData = [
|
||||||
"origin" => $user->getId(),
|
"origin" => $user->getId(),
|
||||||
|
@ -156,55 +166,54 @@ abstract class Postable extends Attachable
|
||||||
"target" => $this->getRecord()->id,
|
"target" => $this->getRecord()->id,
|
||||||
];
|
];
|
||||||
|
|
||||||
if($liked) {
|
if ($liked) {
|
||||||
if(!$this->hasLikeFrom($user)) {
|
if (!$this->hasLikeFrom($user)) {
|
||||||
DB::i()->getContext()->table("likes")->insert($searchData);
|
DB::i()->getContext()->table("likes")->insert($searchData);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if($this->hasLikeFrom($user)) {
|
if ($this->hasLikeFrom($user)) {
|
||||||
DB::i()->getContext()->table("likes")->where($searchData)->delete();
|
DB::i()->getContext()->table("likes")->where($searchData)->delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasLikeFrom(User $user): bool
|
public function hasLikeFrom(User $user): bool
|
||||||
{
|
{
|
||||||
$searchData = [
|
$searchData = [
|
||||||
"origin" => $user->getId(),
|
"origin" => $user->getId(),
|
||||||
"model" => static::class,
|
"model" => static::class,
|
||||||
"target" => $this->getRecord()->id,
|
"target" => $this->getRecord()->id,
|
||||||
];
|
];
|
||||||
|
|
||||||
return sizeof(DB::i()->getContext()->table("likes")->where($searchData)) > 0;
|
return sizeof(DB::i()->getContext()->table("likes")->where($searchData)) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setVirtual_Id(int $id): void
|
public function setVirtual_Id(int $id): void
|
||||||
{
|
{
|
||||||
throw new ISE("Setting virtual id manually is forbidden");
|
throw new ISE("Setting virtual id manually is forbidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
function save(?bool $log = false): void
|
public function save(?bool $log = false): void
|
||||||
{
|
{
|
||||||
$vref = $this->upperNodeReferenceColumnName;
|
$vref = $this->upperNodeReferenceColumnName;
|
||||||
|
|
||||||
$vid = $this->getRecord()->{$vref} ?? $this->changes[$vref];
|
$vid = $this->getRecord()->{$vref} ?? $this->changes[$vref];
|
||||||
if(!$vid)
|
if (!$vid) {
|
||||||
throw new ISE("Can't presist post due to inability to calculate it's $vref post count. Have you set it?");
|
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));
|
$pCount = sizeof($this->getTable()->where($vref, $vid));
|
||||||
if(is_null($this->getRecord())) {
|
if (is_null($this->getRecord())) {
|
||||||
# lol allow ppl to taint created value
|
# lol allow ppl to taint created value
|
||||||
if(!isset($this->changes["created"]))
|
if (!isset($this->changes["created"])) {
|
||||||
$this->stateChanges("created", time());
|
$this->stateChanges("created", time());
|
||||||
|
}
|
||||||
|
|
||||||
$this->stateChanges("virtual_id", $pCount + 1);
|
$this->stateChanges("virtual_id", $pCount + 1);
|
||||||
} /*else {
|
} /*else {
|
||||||
$this->stateChanges("edited", time());
|
$this->stateChanges("edited", time());
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
parent::save($log);
|
parent::save($log);
|
||||||
}
|
}
|
||||||
|
|
||||||
use Traits\TAttachmentHost;
|
|
||||||
use Traits\TOwnable;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,161 +1,177 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
namespace openvk\Web\Models\Entities;
|
|
||||||
use openvk\Web\Util\DateTime;
|
declare(strict_types=1);
|
||||||
use Nette\Database\Table\ActiveRow;
|
|
||||||
use openvk\Web\Models\RowModel;
|
namespace openvk\Web\Models\Entities;
|
||||||
use openvk\Web\Models\Entities\Club;
|
|
||||||
use Chandler\Database\DatabaseConnection;
|
use openvk\Web\Util\DateTime;
|
||||||
use openvk\Web\Models\Repositories\{Applications, Comments, Notes, Reports, Audios, Documents, Users, Posts, Photos, Videos, Clubs};
|
use Nette\Database\Table\ActiveRow;
|
||||||
use Chandler\Database\DatabaseConnection as DB;
|
use openvk\Web\Models\RowModel;
|
||||||
use Nette\InvalidStateException as ISE;
|
use openvk\Web\Models\Entities\Club;
|
||||||
use Nette\Database\Table\Selection;
|
use Chandler\Database\DatabaseConnection;
|
||||||
|
use openvk\Web\Models\Repositories\{Applications, Comments, Notes, Reports, Audios, Documents, Users, Posts, Photos, Videos, Clubs};
|
||||||
class Report extends RowModel
|
use Chandler\Database\DatabaseConnection as DB;
|
||||||
{
|
use Nette\InvalidStateException as ISE;
|
||||||
protected $tableName = "reports";
|
use Nette\Database\Table\Selection;
|
||||||
|
|
||||||
function getId(): int
|
class Report extends RowModel
|
||||||
{
|
{
|
||||||
return $this->getRecord()->id;
|
protected $tableName = "reports";
|
||||||
}
|
|
||||||
|
public function getId(): int
|
||||||
function getStatus(): int
|
{
|
||||||
{
|
return $this->getRecord()->id;
|
||||||
return $this->getRecord()->status;
|
}
|
||||||
}
|
|
||||||
|
public function getStatus(): int
|
||||||
function getContentType(): string
|
{
|
||||||
{
|
return $this->getRecord()->status;
|
||||||
return $this->getRecord()->type;
|
}
|
||||||
}
|
|
||||||
|
public function getContentType(): string
|
||||||
function getReason(): string
|
{
|
||||||
{
|
return $this->getRecord()->type;
|
||||||
return $this->getRecord()->reason;
|
}
|
||||||
}
|
|
||||||
|
public function getReason(): string
|
||||||
function getTime(): DateTime
|
{
|
||||||
{
|
return $this->getRecord()->reason;
|
||||||
return new DateTime($this->getRecord()->date);
|
}
|
||||||
}
|
|
||||||
|
public function getTime(): DateTime
|
||||||
function isDeleted(): bool
|
{
|
||||||
{
|
return new DateTime($this->getRecord()->date);
|
||||||
if ($this->getRecord()->deleted === 0)
|
}
|
||||||
{
|
|
||||||
return false;
|
public function isDeleted(): bool
|
||||||
} elseif ($this->getRecord()->deleted === 1) {
|
{
|
||||||
return true;
|
if ($this->getRecord()->deleted === 0) {
|
||||||
}
|
return false;
|
||||||
}
|
} elseif ($this->getRecord()->deleted === 1) {
|
||||||
|
return true;
|
||||||
function authorId(): int
|
}
|
||||||
{
|
}
|
||||||
return $this->getRecord()->user_id;
|
|
||||||
}
|
public function authorId(): int
|
||||||
|
{
|
||||||
function getUser(): User
|
return $this->getRecord()->user_id;
|
||||||
{
|
}
|
||||||
return (new Users)->get((int) $this->getRecord()->user_id);
|
|
||||||
}
|
public function getUser(): User
|
||||||
|
{
|
||||||
function getContentId(): int
|
return (new Users())->get((int) $this->getRecord()->user_id);
|
||||||
{
|
}
|
||||||
return (int) $this->getRecord()->target_id;
|
|
||||||
}
|
public function getContentId(): int
|
||||||
|
{
|
||||||
function getContentObject()
|
return (int) $this->getRecord()->target_id;
|
||||||
{
|
}
|
||||||
if ($this->getContentType() == "post") return (new Posts)->get($this->getContentId());
|
|
||||||
else if ($this->getContentType() == "photo") return (new Photos)->get($this->getContentId());
|
public function getContentObject()
|
||||||
else if ($this->getContentType() == "video") return (new Videos)->get($this->getContentId());
|
{
|
||||||
else if ($this->getContentType() == "group") return (new Clubs)->get($this->getContentId());
|
if ($this->getContentType() == "post") {
|
||||||
else if ($this->getContentType() == "comment") return (new Comments)->get($this->getContentId());
|
return (new Posts())->get($this->getContentId());
|
||||||
else if ($this->getContentType() == "note") return (new Notes)->get($this->getContentId());
|
} elseif ($this->getContentType() == "photo") {
|
||||||
else if ($this->getContentType() == "app") return (new Applications)->get($this->getContentId());
|
return (new Photos())->get($this->getContentId());
|
||||||
else if ($this->getContentType() == "user") return (new Users)->get($this->getContentId());
|
} elseif ($this->getContentType() == "video") {
|
||||||
else if ($this->getContentType() == "audio") return (new Audios)->get($this->getContentId());
|
return (new Videos())->get($this->getContentId());
|
||||||
else if ($this->getContentType() == "doc") return (new Documents)->get($this->getContentId());
|
} elseif ($this->getContentType() == "group") {
|
||||||
else return null;
|
return (new Clubs())->get($this->getContentId());
|
||||||
}
|
} elseif ($this->getContentType() == "comment") {
|
||||||
|
return (new Comments())->get($this->getContentId());
|
||||||
function getAuthor(): RowModel
|
} elseif ($this->getContentType() == "note") {
|
||||||
{
|
return (new Notes())->get($this->getContentId());
|
||||||
return $this->getContentObject()->getOwner();
|
} elseif ($this->getContentType() == "app") {
|
||||||
}
|
return (new Applications())->get($this->getContentId());
|
||||||
|
} elseif ($this->getContentType() == "user") {
|
||||||
function getReportAuthor(): User
|
return (new Users())->get($this->getContentId());
|
||||||
{
|
} elseif ($this->getContentType() == "audio") {
|
||||||
return (new Users)->get($this->getRecord()->user_id);
|
return (new Audios())->get($this->getContentId());
|
||||||
}
|
} elseif ($this->getContentType() == "doc") {
|
||||||
|
return (new Documents())->get($this->getContentId());
|
||||||
function banUser($initiator)
|
} else {
|
||||||
{
|
return null;
|
||||||
$reason = $this->getContentType() !== "user" ? ("**content-" . $this->getContentType() . "-" . $this->getContentId() . "**") : ("Подозрительная активность");
|
}
|
||||||
$this->getAuthor()->ban($reason, false, time() + $this->getAuthor()->getNewBanTime(), $initiator);
|
}
|
||||||
}
|
|
||||||
|
public function getAuthor(): RowModel
|
||||||
function deleteContent()
|
{
|
||||||
{
|
return $this->getContentObject()->getOwner();
|
||||||
if ($this->getContentType() !== "user") {
|
}
|
||||||
$pubTime = $this->getContentObject()->getPublicationTime();
|
|
||||||
if (method_exists($this->getContentObject(), "getName")) {
|
public function getReportAuthor(): User
|
||||||
$name = $this->getContentObject()->getName();
|
{
|
||||||
$placeholder = "$pubTime ($name)";
|
return (new Users())->get($this->getRecord()->user_id);
|
||||||
} else {
|
}
|
||||||
$placeholder = "$pubTime";
|
|
||||||
}
|
public function banUser($initiator)
|
||||||
|
{
|
||||||
if ($this->getAuthor() instanceof Club) {
|
$reason = $this->getContentType() !== "user" ? ("**content-" . $this->getContentType() . "-" . $this->getContentId() . "**") : ("Подозрительная активность");
|
||||||
$name = $this->getAuthor()->getName();
|
$this->getAuthor()->ban($reason, false, time() + $this->getAuthor()->getNewBanTime(), $initiator);
|
||||||
$this->getAuthor()->getOwner()->adminNotify("Ваш контент, который опубликовали $placeholder в созданной вами группе \"$name\" был удалён модераторами инстанса. За повторные или серьёзные нарушения группу могут заблокировать.");
|
}
|
||||||
} else {
|
|
||||||
$this->getAuthor()->adminNotify("Ваш контент, который вы опубликовали $placeholder был удалён модераторами инстанса. За повторные или серьёзные нарушения вас могут заблокировать.");
|
public function deleteContent()
|
||||||
}
|
{
|
||||||
$this->getContentObject()->delete($this->getContentType() !== "app");
|
if ($this->getContentType() !== "user") {
|
||||||
}
|
$pubTime = $this->getContentObject()->getPublicationTime();
|
||||||
|
if (method_exists($this->getContentObject(), "getName")) {
|
||||||
$this->delete();
|
$name = $this->getContentObject()->getName();
|
||||||
}
|
$placeholder = "$pubTime ($name)";
|
||||||
|
} else {
|
||||||
function getDuplicates(): \Traversable
|
$placeholder = "$pubTime";
|
||||||
{
|
}
|
||||||
return (new Reports)->getDuplicates($this->getContentType(), $this->getContentId(), $this->getId());
|
|
||||||
}
|
if ($this->getAuthor() instanceof Club) {
|
||||||
|
$name = $this->getAuthor()->getName();
|
||||||
function getDuplicatesCount(): int
|
$this->getAuthor()->getOwner()->adminNotify("Ваш контент, который опубликовали $placeholder в созданной вами группе \"$name\" был удалён модераторами инстанса. За повторные или серьёзные нарушения группу могут заблокировать.");
|
||||||
{
|
} else {
|
||||||
return count(iterator_to_array($this->getDuplicates()));
|
$this->getAuthor()->adminNotify("Ваш контент, который вы опубликовали $placeholder был удалён модераторами инстанса. За повторные или серьёзные нарушения вас могут заблокировать.");
|
||||||
}
|
}
|
||||||
|
$this->getContentObject()->delete($this->getContentType() !== "app");
|
||||||
function hasDuplicates(): bool
|
}
|
||||||
{
|
|
||||||
return $this->getDuplicatesCount() > 0;
|
$this->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getContentName(): string
|
public function getDuplicates(): \Traversable
|
||||||
{
|
{
|
||||||
$content_object = $this->getContentObject();
|
return (new Reports())->getDuplicates($this->getContentType(), $this->getContentId(), $this->getId());
|
||||||
if(!$content_object) {
|
}
|
||||||
return 'unknown';
|
|
||||||
}
|
public function getDuplicatesCount(): int
|
||||||
|
{
|
||||||
if (method_exists($content_object, "getCanonicalName"))
|
return count(iterator_to_array($this->getDuplicates()));
|
||||||
return $content_object->getCanonicalName();
|
}
|
||||||
|
|
||||||
return $this->getContentType() . " #" . $this->getContentId();
|
public function hasDuplicates(): bool
|
||||||
}
|
{
|
||||||
|
return $this->getDuplicatesCount() > 0;
|
||||||
public function delete(bool $softly = true): void
|
}
|
||||||
{
|
|
||||||
if ($this->hasDuplicates()) {
|
public function getContentName(): string
|
||||||
foreach ($this->getDuplicates() as $duplicate) {
|
{
|
||||||
$duplicate->setDeleted(1);
|
$content_object = $this->getContentObject();
|
||||||
$duplicate->save();
|
if (!$content_object) {
|
||||||
}
|
return 'unknown';
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setDeleted(1);
|
if (method_exists($content_object, "getCanonicalName")) {
|
||||||
$this->save();
|
return $content_object->getCanonicalName();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return $this->getContentType() . " #" . $this->getContentId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete(bool $softly = true): void
|
||||||
|
{
|
||||||
|
if ($this->hasDuplicates()) {
|
||||||
|
foreach ($this->getDuplicates() as $duplicate) {
|
||||||
|
$duplicate->setDeleted(1);
|
||||||
|
$duplicate->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setDeleted(1);
|
||||||
|
$this->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Models\Repositories\Users;
|
use openvk\Web\Models\Repositories\Users;
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
|
|
||||||
|
@ -7,33 +11,33 @@ class SupportAgent extends RowModel
|
||||||
{
|
{
|
||||||
protected $tableName = "support_names";
|
protected $tableName = "support_names";
|
||||||
|
|
||||||
function getAgentId(): int
|
public function getAgentId(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->agent;
|
return $this->getRecord()->agent;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getName(): ?string
|
public function getName(): ?string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->name;
|
return $this->getRecord()->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCanonicalName(): string
|
public function getCanonicalName(): string
|
||||||
{
|
{
|
||||||
return $this->getName();
|
return $this->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAvatarURL(): ?string
|
public function getAvatarURL(): ?string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->icon;
|
return $this->getRecord()->icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isShowNumber(): int
|
public function isShowNumber(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->numerate;
|
return $this->getRecord()->numerate;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRealName(): string
|
public function getRealName(): string
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getAgentId())->getCanonicalName();
|
return (new Users())->get($this->getAgentId())->getCanonicalName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +1,42 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Models\Repositories\Users;
|
use openvk\Web\Models\Repositories\Users;
|
||||||
|
|
||||||
class SupportAlias extends RowModel
|
class SupportAlias extends RowModel
|
||||||
{
|
{
|
||||||
protected $tableName = "support_names";
|
protected $tableName = "support_names";
|
||||||
|
|
||||||
function getUser(): User
|
public function getUser(): User
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getRecord()->agent);
|
return (new Users())->get($this->getRecord()->agent);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getName(): string
|
public function getName(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->name;
|
return $this->getRecord()->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIcon(): ?string
|
public function getIcon(): ?string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->icon;
|
return $this->getRecord()->icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldAppendNumber(): bool
|
public function shouldAppendNumber(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->numerate;
|
return (bool) $this->getRecord()->numerate;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAgent(User $agent): void
|
public function setAgent(User $agent): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("agent", $agent->getId());
|
$this->stateChanges("agent", $agent->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
function setNumeration(bool $numerate): void
|
public function setNumeration(bool $numerate): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("numerate", $numerate);
|
$this->stateChanges("numerate", $numerate);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,41 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Models\Repositories\Users;
|
use openvk\Web\Models\Repositories\Users;
|
||||||
|
|
||||||
class Ticket extends RowModel
|
class Ticket extends RowModel
|
||||||
{
|
{
|
||||||
|
use Traits\TRichText;
|
||||||
protected $tableName = "tickets";
|
protected $tableName = "tickets";
|
||||||
|
|
||||||
private $overrideContentColumn = "text";
|
private $overrideContentColumn = "text";
|
||||||
|
|
||||||
function getId(): int
|
public function getId(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->id;
|
return $this->getRecord()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStatus(): string
|
public function getStatus(): string
|
||||||
{
|
{
|
||||||
return tr("support_status_" . $this->getRecord()->type);
|
return tr("support_status_" . $this->getRecord()->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getType(): int
|
public function getType(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->type;
|
return $this->getRecord()->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getName(): string
|
public function getName(): string
|
||||||
{
|
{
|
||||||
return ovk_proc_strtr($this->getRecord()->name, 100);
|
return ovk_proc_strtr($this->getRecord()->name, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getContext(): string
|
public function getContext(): string
|
||||||
{
|
{
|
||||||
$text = $this->getRecord()->text;
|
$text = $this->getRecord()->text;
|
||||||
$text = $this->formatLinks($text);
|
$text = $this->formatLinks($text);
|
||||||
|
@ -38,31 +43,29 @@ class Ticket extends RowModel
|
||||||
$text = nl2br($text);
|
$text = nl2br($text);
|
||||||
return $text;
|
return $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTime(): DateTime
|
public function getTime(): DateTime
|
||||||
{
|
{
|
||||||
return new DateTime($this->getRecord()->created);
|
return new DateTime($this->getRecord()->created);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDeleted(): bool
|
public function isDeleted(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->deleted;
|
return (bool) $this->getRecord()->deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUser(): user
|
public function getUser(): user
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getRecord()->user_id);
|
return (new Users())->get($this->getRecord()->user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUserId(): int
|
public function getUserId(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->user_id;
|
return $this->getRecord()->user_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAd(): bool /* Эх, костыли... */
|
public function isAd(): bool /* Эх, костыли... */
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
use Traits\TRichText;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,100 +1,112 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Models\Repositories\{Users, SupportAliases, Tickets};
|
use openvk\Web\Models\Repositories\{Users, SupportAliases, Tickets};
|
||||||
|
|
||||||
class TicketComment extends RowModel
|
class TicketComment extends RowModel
|
||||||
{
|
{
|
||||||
|
use Traits\TRichText;
|
||||||
protected $tableName = "tickets_comments";
|
protected $tableName = "tickets_comments";
|
||||||
|
|
||||||
private $overrideContentColumn = "text";
|
private $overrideContentColumn = "text";
|
||||||
|
|
||||||
private function getSupportAlias(): ?SupportAlias
|
private function getSupportAlias(): ?SupportAlias
|
||||||
{
|
{
|
||||||
return (new SupportAliases)->get($this->getUser()->getId());
|
return (new SupportAliases())->get($this->getUser()->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
function getId(): int
|
public function getId(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->id;
|
return $this->getRecord()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUType(): int
|
public function getUType(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->user_type;
|
return $this->getRecord()->user_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUser(): User
|
public function getUser(): User
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getRecord()->user_id);
|
return (new Users())->get($this->getRecord()->user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTicket(): Ticket
|
public function getTicket(): Ticket
|
||||||
{
|
{
|
||||||
return (new Tickets)->get($this->getRecord()->ticket_id);
|
return (new Tickets())->get($this->getRecord()->ticket_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAuthorName(): string
|
public function getAuthorName(): string
|
||||||
{
|
{
|
||||||
if($this->getUType() === 0)
|
if ($this->getUType() === 0) {
|
||||||
return $this->getUser()->getCanonicalName();
|
return $this->getUser()->getCanonicalName();
|
||||||
|
}
|
||||||
|
|
||||||
$alias = $this->getSupportAlias();
|
$alias = $this->getSupportAlias();
|
||||||
if(!$alias)
|
if (!$alias) {
|
||||||
return tr("helpdesk_agent") . " #" . $this->getAgentNumber();
|
return tr("helpdesk_agent") . " #" . $this->getAgentNumber();
|
||||||
|
}
|
||||||
|
|
||||||
$name = $alias->getName();
|
$name = $alias->getName();
|
||||||
if($alias->shouldAppendNumber())
|
if ($alias->shouldAppendNumber()) {
|
||||||
$name .= " №" . $this->getAgentNumber();
|
$name .= " №" . $this->getAgentNumber();
|
||||||
|
}
|
||||||
|
|
||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAvatar(): string
|
public function getAvatar(): string
|
||||||
{
|
{
|
||||||
if($this->getUType() === 0)
|
if ($this->getUType() === 0) {
|
||||||
return $this->getUser()->getAvatarUrl();
|
return $this->getUser()->getAvatarUrl();
|
||||||
|
}
|
||||||
|
|
||||||
$default = "/assets/packages/static/openvk/img/support.jpeg";
|
$default = "/assets/packages/static/openvk/img/support.jpeg";
|
||||||
$alias = $this->getSupportAlias();
|
$alias = $this->getSupportAlias();
|
||||||
|
|
||||||
return is_null($alias) ? $default : ($alias->getIcon() ?? $default);
|
return is_null($alias) ? $default : ($alias->getIcon() ?? $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAgentNumber(): ?string
|
public function getAgentNumber(): ?string
|
||||||
{
|
{
|
||||||
if($this->getUType() === 0)
|
if ($this->getUType() === 0) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
$salt = "kiraMiki";
|
$salt = "kiraMiki";
|
||||||
$hash = $this->getUser()->getId() . CHANDLER_ROOT_CONF["security"]["secret"] . $salt;
|
$hash = $this->getUser()->getId() . CHANDLER_ROOT_CONF["security"]["secret"] . $salt;
|
||||||
$hash = hexdec(substr(hash("adler32", $hash), 0, 3));
|
$hash = hexdec(substr(hash("adler32", $hash), 0, 3));
|
||||||
$hash = ceil(($hash * 999) / 4096); # proportionalize to 0-999
|
$hash = ceil(($hash * 999) / 4096); # proportionalize to 0-999
|
||||||
|
|
||||||
return str_pad((string) $hash, 3, "0", STR_PAD_LEFT);
|
return str_pad((string) $hash, 3, "0", STR_PAD_LEFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getColorRotation(): ?int
|
public function getColorRotation(): ?int
|
||||||
{
|
{
|
||||||
if(is_null($agent = $this->getAgentNumber()))
|
if (is_null($agent = $this->getAgentNumber())) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
if(!is_null($this->getSupportAlias()))
|
|
||||||
|
if (!is_null($this->getSupportAlias())) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
$agent = (int) $agent;
|
$agent = (int) $agent;
|
||||||
$rotation = $agent > 500 ? ( ($agent * 360) / 999 ) : $agent; # cap at 360deg
|
$rotation = $agent > 500 ? (($agent * 360) / 999) : $agent; # cap at 360deg
|
||||||
$values = [0, 45, 160, 220, 310, 345]; # good looking colors
|
$values = [0, 45, 160, 220, 310, 345]; # good looking colors
|
||||||
usort($values, function($x, $y) use ($rotation) {
|
usort($values, function ($x, $y) use ($rotation) {
|
||||||
# find closest
|
# find closest
|
||||||
return abs($x - $rotation) - abs($y - $rotation);
|
return abs($x - $rotation) - abs($y - $rotation);
|
||||||
});
|
});
|
||||||
|
|
||||||
return array_shift($values);
|
return array_shift($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getContext(): string
|
public function getContext(): string
|
||||||
{
|
{
|
||||||
$text = $this->getRecord()->text;
|
$text = $this->getRecord()->text;
|
||||||
$text = $this->formatLinks($text);
|
$text = $this->formatLinks($text);
|
||||||
|
@ -102,35 +114,34 @@ class TicketComment extends RowModel
|
||||||
$text = nl2br($text);
|
$text = nl2br($text);
|
||||||
return $text;
|
return $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTime(): DateTime
|
public function getTime(): DateTime
|
||||||
{
|
{
|
||||||
return new DateTime($this->getRecord()->created);
|
return new DateTime($this->getRecord()->created);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAd(): bool
|
public function isAd(): bool
|
||||||
{
|
{
|
||||||
return false; # Кооостыыыль!!!
|
return false; # Кооостыыыль!!!
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMark(): ?int
|
public function getMark(): ?int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->mark;
|
return $this->getRecord()->mark;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isLikedByUser(): ?bool
|
public function isLikedByUser(): ?bool
|
||||||
{
|
{
|
||||||
$mark = $this->getMark();
|
$mark = $this->getMark();
|
||||||
if(is_null($mark))
|
if (is_null($mark)) {
|
||||||
return NULL;
|
return null;
|
||||||
else
|
} else {
|
||||||
return $mark === 1;
|
return $mark === 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDeleted(): bool
|
public function isDeleted(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->deleted;
|
return (bool) $this->getRecord()->deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
use Traits\TRichText;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Models\Repositories\Clubs;
|
use openvk\Web\Models\Repositories\Clubs;
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
|
@ -11,116 +15,118 @@ class Topic extends Postable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* May return fake owner (group), if flags are [1, (*)]
|
* May return fake owner (group), if flags are [1, (*)]
|
||||||
*
|
*
|
||||||
* @param bool $honourFlags - check flags
|
* @param bool $honourFlags - check flags
|
||||||
*/
|
*/
|
||||||
function getOwner(bool $honourFlags = true, bool $real = false): RowModel
|
public function getOwner(bool $honourFlags = true, bool $real = false): RowModel
|
||||||
{
|
{
|
||||||
if($honourFlags && $this->isPostedOnBehalfOfGroup())
|
if ($honourFlags && $this->isPostedOnBehalfOfGroup()) {
|
||||||
return $this->getClub();
|
return $this->getClub();
|
||||||
|
}
|
||||||
|
|
||||||
return parent::getOwner($real);
|
return parent::getOwner($real);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getClub(): Club
|
public function getClub(): Club
|
||||||
{
|
{
|
||||||
return (new Clubs)->get($this->getRecord()->group);
|
return (new Clubs())->get($this->getRecord()->group);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTitle(): string
|
public function getTitle(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->title;
|
return $this->getRecord()->title;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isClosed(): bool
|
public function isClosed(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->closed;
|
return (bool) $this->getRecord()->closed;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPinned(): bool
|
public function isPinned(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->pinned;
|
return (bool) $this->getRecord()->pinned;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPrettyId(): string
|
public function getPrettyId(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->group . "_" . $this->getVirtualId();
|
return $this->getRecord()->group . "_" . $this->getVirtualId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPostedOnBehalfOfGroup(): bool
|
public function isPostedOnBehalfOfGroup(): bool
|
||||||
{
|
{
|
||||||
return ($this->getRecord()->flags & 0b10000000) > 0;
|
return ($this->getRecord()->flags & 0b10000000) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDeleted(): bool
|
public function isDeleted(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->getRecord()->deleted;
|
return (bool) $this->getRecord()->deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBeModifiedBy(User $user): bool
|
public function canBeModifiedBy(User $user): bool
|
||||||
{
|
{
|
||||||
return $this->getOwner(false)->getId() === $user->getId() || $this->getClub()->canBeModifiedBy($user);
|
return $this->getOwner(false)->getId() === $user->getId() || $this->getClub()->canBeModifiedBy($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLastComment(): ?Comment
|
public function getLastComment(): ?Comment
|
||||||
{
|
{
|
||||||
$array = iterator_to_array($this->getLastComments(1));
|
$array = iterator_to_array($this->getLastComments(1));
|
||||||
return isset($array[0]) ? $array[0] : NULL;
|
return $array[0] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFirstComment(): ?Comment
|
public function getFirstComment(): ?Comment
|
||||||
{
|
{
|
||||||
$array = iterator_to_array($this->getComments(1));
|
$array = iterator_to_array($this->getComments(1));
|
||||||
return $array[0] ?? NULL;
|
return $array[0] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUpdateTime(): DateTime
|
public function getUpdateTime(): DateTime
|
||||||
{
|
{
|
||||||
$lastComment = $this->getLastComment();
|
$lastComment = $this->getLastComment();
|
||||||
if(!is_null($lastComment))
|
if (!is_null($lastComment)) {
|
||||||
return $lastComment->getPublicationTime();
|
return $lastComment->getPublicationTime();
|
||||||
else
|
} else {
|
||||||
return $this->getEditTime() ?? $this->getPublicationTime();
|
return $this->getEditTime() ?? $this->getPublicationTime();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteTopic(): void
|
public function deleteTopic(): void
|
||||||
{
|
{
|
||||||
$this->setDeleted(1);
|
$this->setDeleted(1);
|
||||||
$this->unwire();
|
$this->unwire();
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
function toVkApiStruct(int $preview = 0, int $preview_length = 90): object
|
public function toVkApiStruct(int $preview = 0, int $preview_length = 90): object
|
||||||
{
|
{
|
||||||
$res = (object)[];
|
$res = (object) [];
|
||||||
|
|
||||||
$res->id = $this->getId();
|
$res->id = $this->getId();
|
||||||
$res->title = $this->getTitle();
|
$res->title = $this->getTitle();
|
||||||
$res->created = $this->getPublicationTime()->timestamp();
|
$res->created = $this->getPublicationTime()->timestamp();
|
||||||
|
|
||||||
if($this->getOwner() instanceof User) {
|
if ($this->getOwner() instanceof User) {
|
||||||
$res->created_by = $this->getOwner()->getId();
|
$res->created_by = $this->getOwner()->getId();
|
||||||
} else {
|
} else {
|
||||||
$res->created_by = $this->getOwner()->getId() * -1;
|
$res->created_by = $this->getOwner()->getId() * -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$res->updated = $this->getUpdateTime()->timestamp();
|
$res->updated = $this->getUpdateTime()->timestamp();
|
||||||
|
|
||||||
if($this->getLastComment()) {
|
if ($this->getLastComment()) {
|
||||||
if($this->getLastComment()->getOwner() instanceof User) {
|
if ($this->getLastComment()->getOwner() instanceof User) {
|
||||||
$res->updated_by = $this->getLastComment()->getOwner()->getId();
|
$res->updated_by = $this->getLastComment()->getOwner()->getId();
|
||||||
} else {
|
} else {
|
||||||
$res->updated_by = $this->getLastComment()->getOwner()->getId() * -1;
|
$res->updated_by = $this->getLastComment()->getOwner()->getId() * -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$res->is_closed = (int)$this->isClosed();
|
$res->is_closed = (int) $this->isClosed();
|
||||||
$res->is_fixed = (int)$this->isPinned();
|
$res->is_fixed = (int) $this->isPinned();
|
||||||
$res->comments = $this->getCommentsCount();
|
$res->comments = $this->getCommentsCount();
|
||||||
|
|
||||||
if($preview == 1) {
|
if ($preview == 1) {
|
||||||
$res->first_comment = $this->getFirstComment() ? ovk_proc_strtr($this->getFirstComment()->getText(false), $preview_length) : NULL;
|
$res->first_comment = $this->getFirstComment() ? ovk_proc_strtr($this->getFirstComment()->getText(false), $preview_length) : null;
|
||||||
$res->last_comment = $this->getLastComment() ? ovk_proc_strtr($this->getLastComment()->getText(false), $preview_length) : NULL;
|
$res->last_comment = $this->getLastComment() ? ovk_proc_strtr($this->getLastComment()->getText(false), $preview_length) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Traits;
|
namespace openvk\Web\Models\Entities\Traits;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\{Attachable, Photo, Video};
|
use openvk\Web\Models\Entities\{Attachable, Photo, Video};
|
||||||
use openvk\Web\Util\Makima\Makima;
|
use openvk\Web\Util\Makima\Makima;
|
||||||
use Chandler\Database\DatabaseConnection;
|
use Chandler\Database\DatabaseConnection;
|
||||||
|
@ -15,31 +19,32 @@ trait TAttachmentHost
|
||||||
"attachable_id" => $attachment->getId(),
|
"attachable_id" => $attachment->getId(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChildren(): \Traversable
|
public function getChildren(): \Traversable
|
||||||
{
|
{
|
||||||
$sel = DatabaseConnection::i()->getContext()
|
$sel = DatabaseConnection::i()->getContext()
|
||||||
->table("attachments")
|
->table("attachments")
|
||||||
->where("target_id", $this->getId())
|
->where("target_id", $this->getId())
|
||||||
->where("attachments.target_type", get_class($this));
|
->where("attachments.target_type", get_class($this));
|
||||||
foreach($sel as $rel) {
|
foreach ($sel as $rel) {
|
||||||
$repoName = $rel->attachable_type . "s";
|
$repoName = $rel->attachable_type . "s";
|
||||||
$repoName = str_replace("Entities", "Repositories", $repoName);
|
$repoName = str_replace("Entities", "Repositories", $repoName);
|
||||||
$repo = new $repoName;
|
$repo = new $repoName();
|
||||||
|
|
||||||
yield $repo->get($rel->attachable_id);
|
yield $repo->get($rel->attachable_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChildrenWithLayout(int $w, int $h = -1): object
|
public function getChildrenWithLayout(int $w, int $h = -1): object
|
||||||
{
|
{
|
||||||
if($h < 0)
|
if ($h < 0) {
|
||||||
$h = $w;
|
$h = $w;
|
||||||
|
}
|
||||||
|
|
||||||
$children = iterator_to_array($this->getChildren());
|
$children = iterator_to_array($this->getChildren());
|
||||||
$skipped = $photos = $result = [];
|
$skipped = $photos = $result = [];
|
||||||
foreach($children as $child) {
|
foreach ($children as $child) {
|
||||||
if($child instanceof Photo || $child instanceof Video && $child->getDimensions()) {
|
if ($child instanceof Photo || $child instanceof Video && $child->getDimensions()) {
|
||||||
$photos[] = $child;
|
$photos[] = $child;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -49,15 +54,16 @@ trait TAttachmentHost
|
||||||
|
|
||||||
$height = "unset";
|
$height = "unset";
|
||||||
$width = $w;
|
$width = $w;
|
||||||
if(sizeof($photos) < 2) {
|
if (sizeof($photos) < 2) {
|
||||||
if(isset($photos[0]))
|
if (isset($photos[0])) {
|
||||||
$result[] = ["100%", "unset", $photos[0], "unset"];
|
$result[] = ["100%", "unset", $photos[0], "unset"];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$mak = new Makima($photos);
|
$mak = new Makima($photos);
|
||||||
$layout = $mak->computeMasonryLayout($w, $h);
|
$layout = $mak->computeMasonryLayout($w, $h);
|
||||||
$height = $layout->height;
|
$height = $layout->height;
|
||||||
$width = $layout->width;
|
$width = $layout->width;
|
||||||
for($i = 0; $i < sizeof($photos); $i++) {
|
for ($i = 0; $i < sizeof($photos); $i++) {
|
||||||
$tile = $layout->tiles[$i];
|
$tile = $layout->tiles[$i];
|
||||||
$result[] = [$tile->width . "px", $tile->height . "px", $photos[$i], "left"];
|
$result[] = [$tile->width . "px", $tile->height . "px", $photos[$i], "left"];
|
||||||
}
|
}
|
||||||
|
@ -70,25 +76,25 @@ trait TAttachmentHost
|
||||||
"extras" => $skipped,
|
"extras" => $skipped,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function attach(Attachable $attachment): void
|
public function attach(Attachable $attachment): void
|
||||||
{
|
{
|
||||||
DatabaseConnection::i()->getContext()
|
DatabaseConnection::i()->getContext()
|
||||||
->table("attachments")
|
->table("attachments")
|
||||||
->insert($this->composeAttachmentRequestData($attachment));
|
->insert($this->composeAttachmentRequestData($attachment));
|
||||||
}
|
}
|
||||||
|
|
||||||
function detach(Attachable $attachment): bool
|
public function detach(Attachable $attachment): bool
|
||||||
{
|
{
|
||||||
$res = DatabaseConnection::i()->getContext()
|
$res = DatabaseConnection::i()->getContext()
|
||||||
->table("attachments")
|
->table("attachments")
|
||||||
->where($this->composeAttachmentRequestData($attachment))
|
->where($this->composeAttachmentRequestData($attachment))
|
||||||
->delete();
|
->delete();
|
||||||
|
|
||||||
return $res > 0;
|
return $res > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function unwire(): void
|
public function unwire(): void
|
||||||
{
|
{
|
||||||
$this->getRecord()
|
$this->getRecord()
|
||||||
->related("attachments.target_id")
|
->related("attachments.target_id")
|
||||||
|
|
|
@ -1,27 +1,38 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Traits;
|
namespace openvk\Web\Models\Entities\Traits;
|
||||||
|
|
||||||
use openvk\Web\Models\Repositories\Audios;
|
use openvk\Web\Models\Repositories\Audios;
|
||||||
use Chandler\Database\DatabaseConnection;
|
use Chandler\Database\DatabaseConnection;
|
||||||
|
|
||||||
trait TAudioStatuses
|
trait TAudioStatuses
|
||||||
{
|
{
|
||||||
function isBroadcastEnabled(): bool
|
public function isBroadcastEnabled(): bool
|
||||||
{
|
{
|
||||||
if($this->getRealId() < 0) return true;
|
if ($this->getRealId() < 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return (bool) $this->getRecord()->audio_broadcast_enabled;
|
return (bool) $this->getRecord()->audio_broadcast_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentAudioStatus()
|
public function getCurrentAudioStatus()
|
||||||
{
|
{
|
||||||
if(!$this->isBroadcastEnabled()) return NULL;
|
if (!$this->isBroadcastEnabled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
$audioId = $this->getRecord()->last_played_track;
|
$audioId = $this->getRecord()->last_played_track;
|
||||||
|
|
||||||
if(!$audioId) return NULL;
|
if (!$audioId) {
|
||||||
$audio = (new Audios)->get($audioId);
|
return null;
|
||||||
|
}
|
||||||
|
$audio = (new Audios())->get($audioId);
|
||||||
|
|
||||||
if(!$audio || $audio->isDeleted())
|
if (!$audio || $audio->isDeleted()) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
$listensTable = DatabaseConnection::i()->getContext()->table("audio_listens");
|
$listensTable = DatabaseConnection::i()->getContext()->table("audio_listens");
|
||||||
$lastListen = $listensTable->where([
|
$lastListen = $listensTable->where([
|
||||||
|
@ -30,9 +41,10 @@ trait TAudioStatuses
|
||||||
"time >" => (time() - $audio->getLength()) - 10,
|
"time >" => (time() - $audio->getLength()) - 10,
|
||||||
])->fetch();
|
])->fetch();
|
||||||
|
|
||||||
if($lastListen)
|
if ($lastListen) {
|
||||||
return $audio;
|
return $audio;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,44 +1,54 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Traits;
|
namespace openvk\Web\Models\Entities\Traits;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\Photo;
|
use openvk\Web\Models\Entities\Photo;
|
||||||
use openvk\Web\Models\Repositories\Photos;
|
use openvk\Web\Models\Repositories\Photos;
|
||||||
|
|
||||||
trait TBackDrops {
|
trait TBackDrops
|
||||||
function getBackDropPictureURLs(): ?array
|
{
|
||||||
|
public function getBackDropPictureURLs(): ?array
|
||||||
{
|
{
|
||||||
$photo1 = $this->getRecord()->backdrop_1;
|
$photo1 = $this->getRecord()->backdrop_1;
|
||||||
$photo2 = $this->getRecord()->backdrop_2;
|
$photo2 = $this->getRecord()->backdrop_2;
|
||||||
if(is_null($photo1) && is_null($photo2))
|
if (is_null($photo1) && is_null($photo2)) {
|
||||||
return NULL;
|
return null;
|
||||||
|
}
|
||||||
$photo1obj = $photo2obj = NULL;
|
|
||||||
if(!is_null($photo1))
|
$photo1obj = $photo2obj = null;
|
||||||
$photo1obj = (new Photos)->get($photo1);
|
if (!is_null($photo1)) {
|
||||||
if(!is_null($photo2))
|
$photo1obj = (new Photos())->get($photo1);
|
||||||
$photo2obj = (new Photos)->get($photo2);
|
}
|
||||||
|
if (!is_null($photo2)) {
|
||||||
if(is_null($photo1obj) && is_null($photo2obj))
|
$photo2obj = (new Photos())->get($photo2);
|
||||||
return NULL;
|
}
|
||||||
|
|
||||||
|
if (is_null($photo1obj) && is_null($photo2obj)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
is_null($photo1obj) ? "" : $photo1obj->getURL(),
|
is_null($photo1obj) ? "" : $photo1obj->getURL(),
|
||||||
is_null($photo2obj) ? "" : $photo2obj->getURL(),
|
is_null($photo2obj) ? "" : $photo2obj->getURL(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function setBackDropPictures(?Photo $first, ?Photo $second): void
|
public function setBackDropPictures(?Photo $first, ?Photo $second): void
|
||||||
{
|
{
|
||||||
if(!is_null($first))
|
if (!is_null($first)) {
|
||||||
$this->stateChanges("backdrop_1", $first->getId());
|
$this->stateChanges("backdrop_1", $first->getId());
|
||||||
|
}
|
||||||
if(!is_null($second))
|
|
||||||
|
if (!is_null($second)) {
|
||||||
$this->stateChanges("backdrop_2", $second->getId());
|
$this->stateChanges("backdrop_2", $second->getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function unsetBackDropPictures(): void
|
public function unsetBackDropPictures(): void
|
||||||
{
|
{
|
||||||
$this->stateChanges("backdrop_1", NULL);
|
$this->stateChanges("backdrop_1", null);
|
||||||
$this->stateChanges("backdrop_2", NULL);
|
$this->stateChanges("backdrop_2", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,20 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Traits;
|
namespace openvk\Web\Models\Entities\Traits;
|
||||||
|
|
||||||
use Chandler\Database\DatabaseConnection;
|
use Chandler\Database\DatabaseConnection;
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
|
|
||||||
trait TIgnorable
|
trait TIgnorable
|
||||||
{
|
{
|
||||||
function isIgnoredBy(User $user = NULL): bool
|
public function isIgnoredBy(User $user = null): bool
|
||||||
{
|
{
|
||||||
if(!$user)
|
if (!$user) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$ctx = DatabaseConnection::i()->getContext();
|
$ctx = DatabaseConnection::i()->getContext();
|
||||||
$data = [
|
$data = [
|
||||||
"owner" => $user->getId(),
|
"owner" => $user->getId(),
|
||||||
|
@ -20,29 +25,29 @@ trait TIgnorable
|
||||||
return $sub->count() > 0;
|
return $sub->count() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addIgnore(User $for_user): bool
|
public function addIgnore(User $for_user): bool
|
||||||
{
|
{
|
||||||
DatabaseConnection::i()->getContext()->table("ignored_sources")->insert([
|
DatabaseConnection::i()->getContext()->table("ignored_sources")->insert([
|
||||||
"owner" => $for_user->getId(),
|
"owner" => $for_user->getId(),
|
||||||
"source" => $this->getRealId(),
|
"source" => $this->getRealId(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeIgnore(User $for_user): bool
|
public function removeIgnore(User $for_user): bool
|
||||||
{
|
{
|
||||||
DatabaseConnection::i()->getContext()->table("ignored_sources")->where([
|
DatabaseConnection::i()->getContext()->table("ignored_sources")->where([
|
||||||
"owner" => $for_user->getId(),
|
"owner" => $for_user->getId(),
|
||||||
"source" => $this->getRealId(),
|
"source" => $this->getRealId(),
|
||||||
])->delete();
|
])->delete();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleIgnore(User $for_user): bool
|
public function toggleIgnore(User $for_user): bool
|
||||||
{
|
{
|
||||||
if($this->isIgnoredBy($for_user)) {
|
if ($this->isIgnoredBy($for_user)) {
|
||||||
$this->removeIgnore($for_user);
|
$this->removeIgnore($for_user);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,28 +1,35 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Traits;
|
namespace openvk\Web\Models\Entities\Traits;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
|
|
||||||
trait TOwnable
|
trait TOwnable
|
||||||
{
|
{
|
||||||
function canBeViewedBy(?User $user = NULL): bool
|
public function canBeViewedBy(?User $user = null): bool
|
||||||
{
|
{
|
||||||
# TODO: #950
|
# TODO: #950
|
||||||
if($this->isDeleted()) {
|
if ($this->isDeleted()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function canBeModifiedBy(User $user): bool
|
public function canBeModifiedBy(User $user): bool
|
||||||
{
|
{
|
||||||
if(method_exists($this, "isCreatedBySystem"))
|
if (method_exists($this, "isCreatedBySystem")) {
|
||||||
if($this->isCreatedBySystem())
|
if ($this->isCreatedBySystem()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
if($this->getRecord()->owner > 0)
|
}
|
||||||
|
|
||||||
|
if ($this->getRecord()->owner > 0) {
|
||||||
return $this->getRecord()->owner === $user->getId();
|
return $this->getRecord()->owner === $user->getId();
|
||||||
else
|
} else {
|
||||||
return $this->getOwner()->canBeModifiedBy($user);
|
return $this->getOwner()->canBeModifiedBy($user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Traits;
|
namespace openvk\Web\Models\Entities\Traits;
|
||||||
|
|
||||||
use openvk\Web\Models\Repositories\{Users, Clubs};
|
use openvk\Web\Models\Repositories\{Users, Clubs};
|
||||||
use Wkhooy\ObsceneCensorRus;
|
use Wkhooy\ObsceneCensorRus;
|
||||||
|
|
||||||
|
@ -8,28 +12,30 @@ trait TRichText
|
||||||
private function formatEmojis(string $text): string
|
private function formatEmojis(string $text): string
|
||||||
{
|
{
|
||||||
$contentColumn = property_exists($this, "overrideContentColumn") ? $this->overrideContentColumn : "content";
|
$contentColumn = property_exists($this, "overrideContentColumn") ? $this->overrideContentColumn : "content";
|
||||||
if(iconv_strlen($this->getRecord()->{$contentColumn}) > OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["emojiProcessingLimit"])
|
if (iconv_strlen($this->getRecord()->{$contentColumn}) > OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["emojiProcessingLimit"]) {
|
||||||
return $text;
|
return $text;
|
||||||
|
}
|
||||||
|
|
||||||
$emojis = \Emoji\detect_emoji($text);
|
$emojis = \Emoji\detect_emoji($text);
|
||||||
$replaced = []; # OVK-113
|
$replaced = []; # OVK-113
|
||||||
foreach($emojis as $emoji) {
|
foreach ($emojis as $emoji) {
|
||||||
$point = explode("-", strtolower($emoji["hex_str"]))[0];
|
$point = explode("-", strtolower($emoji["hex_str"]))[0];
|
||||||
if(in_array($point, $replaced))
|
if (in_array($point, $replaced)) {
|
||||||
continue;
|
continue;
|
||||||
else
|
} else {
|
||||||
$replaced[] = $point;
|
$replaced[] = $point;
|
||||||
|
}
|
||||||
|
|
||||||
$image = "https://abs.twimg.com/emoji/v2/72x72/$point.png";
|
$image = "https://abs.twimg.com/emoji/v2/72x72/$point.png";
|
||||||
$image = "<img src='$image' alt='$emoji[emoji]' ";
|
$image = "<img src='$image' alt='$emoji[emoji]' ";
|
||||||
$image .= "style='max-height:12px; padding-left: 2pt; padding-right: 2pt; vertical-align: bottom;' />";
|
$image .= "style='max-height:12px; padding-left: 2pt; padding-right: 2pt; vertical-align: bottom;' />";
|
||||||
|
|
||||||
$text = str_replace($emoji["emoji"], $image, $text);
|
$text = str_replace($emoji["emoji"], $image, $text);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $text;
|
return $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function formatLinks(string &$text): string
|
private function formatLinks(string &$text): string
|
||||||
{
|
{
|
||||||
return preg_replace_callback(
|
return preg_replace_callback(
|
||||||
|
@ -46,109 +52,116 @@ trait TRichText
|
||||||
if(str_contains($link, $server_domain)) {
|
if(str_contains($link, $server_domain)) {
|
||||||
$replaced_link = str_replace(':' . $_SERVER['SERVER_PORT'], '', $link);
|
$replaced_link = str_replace(':' . $_SERVER['SERVER_PORT'], '', $link);
|
||||||
$replaced_link = str_replace($server_domain, '', $replaced_link);
|
$replaced_link = str_replace($server_domain, '', $replaced_link);
|
||||||
|
|
||||||
return "<a href='$replaced_link' rel='$rel'>$link</a>" . htmlentities($matches[4]);
|
return "<a href='$replaced_link' rel='$rel'>$link</a>" . htmlentities($matches[4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$link = htmlentities(urldecode($link));*/
|
$link = htmlentities(urldecode($link));*/
|
||||||
|
|
||||||
return "<a href='/away.php?to=$href' rel='$rel' target='_blank'>$link</a>" . htmlentities($matches[4]);
|
return "<a href='/away.php?to=$href' rel='$rel' target='_blank'>$link</a>" . htmlentities($matches[4]);
|
||||||
}),
|
}),
|
||||||
$text
|
$text
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function removeZalgo(string $text): string
|
private function removeZalgo(string $text): string
|
||||||
{
|
{
|
||||||
return preg_replace("%\p{M}{3,}%Xu", "", $text);
|
return preg_replace("%\p{M}{3,}%Xu", "", $text);
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveMentions(array $skipUsers = []): \Traversable
|
public function resolveMentions(array $skipUsers = []): \Traversable
|
||||||
{
|
{
|
||||||
$contentColumn = property_exists($this, "overrideContentColumn") ? $this->overrideContentColumn : "content";
|
$contentColumn = property_exists($this, "overrideContentColumn") ? $this->overrideContentColumn : "content";
|
||||||
$text = $this->getRecord()->{$contentColumn};
|
$text = $this->getRecord()->{$contentColumn};
|
||||||
$text = preg_replace("%@([A-Za-z0-9]++) \(((?:[\p{L&}\p{Lo} 0-9]\p{Mn}?)++)\)%Xu", "[$1|$2]", $text);
|
$text = preg_replace("%@([A-Za-z0-9]++) \(((?:[\p{L&}\p{Lo} 0-9]\p{Mn}?)++)\)%Xu", "[$1|$2]", $text);
|
||||||
$text = preg_replace("%([\n\r\s]|^)(@([A-Za-z0-9]++))%Xu", "$1[$3|@$3]", $text);
|
$text = preg_replace("%([\n\r\s]|^)(@([A-Za-z0-9]++))%Xu", "$1[$3|@$3]", $text);
|
||||||
|
|
||||||
$resolvedUsers = $skipUsers;
|
$resolvedUsers = $skipUsers;
|
||||||
$resolvedClubs = [];
|
$resolvedClubs = [];
|
||||||
preg_match_all("%\[([A-Za-z0-9]++)\|((?:[\p{L&}\p{Lo} 0-9@]\p{Mn}?)++)\]%Xu", $text, $links, PREG_PATTERN_ORDER);
|
preg_match_all("%\[([A-Za-z0-9]++)\|((?:[\p{L&}\p{Lo} 0-9@]\p{Mn}?)++)\]%Xu", $text, $links, PREG_PATTERN_ORDER);
|
||||||
foreach($links[1] as $link) {
|
foreach ($links[1] as $link) {
|
||||||
if(preg_match("%^id([0-9]++)$%", $link, $match)) {
|
if (preg_match("%^id([0-9]++)$%", $link, $match)) {
|
||||||
$uid = (int) $match[1];
|
$uid = (int) $match[1];
|
||||||
if(in_array($uid, $resolvedUsers))
|
if (in_array($uid, $resolvedUsers)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$resolvedUsers[] = $uid;
|
$resolvedUsers[] = $uid;
|
||||||
$maybeUser = (new Users)->get($uid);
|
$maybeUser = (new Users())->get($uid);
|
||||||
if($maybeUser)
|
if ($maybeUser) {
|
||||||
yield $maybeUser;
|
yield $maybeUser;
|
||||||
} else if(preg_match("%^(?:club|public|event)([0-9]++)$%", $link, $match)) {
|
}
|
||||||
|
} elseif (preg_match("%^(?:club|public|event)([0-9]++)$%", $link, $match)) {
|
||||||
$cid = (int) $match[1];
|
$cid = (int) $match[1];
|
||||||
if(in_array($cid, $resolvedClubs))
|
if (in_array($cid, $resolvedClubs)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$resolvedClubs[] = $cid;
|
$resolvedClubs[] = $cid;
|
||||||
$maybeClub = (new Clubs)->get($cid);
|
$maybeClub = (new Clubs())->get($cid);
|
||||||
if($maybeClub)
|
if ($maybeClub) {
|
||||||
yield $maybeClub;
|
yield $maybeClub;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$maybeUser = (new Users)->getByShortURL($link);
|
$maybeUser = (new Users())->getByShortURL($link);
|
||||||
if($maybeUser) {
|
if ($maybeUser) {
|
||||||
$uid = $maybeUser->getId();
|
$uid = $maybeUser->getId();
|
||||||
if(in_array($uid, $resolvedUsers))
|
if (in_array($uid, $resolvedUsers)) {
|
||||||
continue;
|
continue;
|
||||||
else
|
} else {
|
||||||
$resolvedUsers[] = $uid;
|
$resolvedUsers[] = $uid;
|
||||||
|
}
|
||||||
|
|
||||||
yield $maybeUser;
|
yield $maybeUser;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$maybeClub = (new Clubs)->getByShortURL($link);
|
$maybeClub = (new Clubs())->getByShortURL($link);
|
||||||
if($maybeClub) {
|
if ($maybeClub) {
|
||||||
$cid = $maybeClub->getId();
|
$cid = $maybeClub->getId();
|
||||||
if(in_array($cid, $resolvedClubs))
|
if (in_array($cid, $resolvedClubs)) {
|
||||||
continue;
|
continue;
|
||||||
else
|
} else {
|
||||||
$resolvedClubs[] = $cid;
|
$resolvedClubs[] = $cid;
|
||||||
|
}
|
||||||
|
|
||||||
yield $maybeClub;
|
yield $maybeClub;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getText(bool $html = true): string
|
public function getText(bool $html = true): string
|
||||||
{
|
{
|
||||||
$contentColumn = property_exists($this, "overrideContentColumn") ? $this->overrideContentColumn : "content";
|
$contentColumn = property_exists($this, "overrideContentColumn") ? $this->overrideContentColumn : "content";
|
||||||
|
|
||||||
$text = htmlspecialchars($this->getRecord()->{$contentColumn}, ENT_DISALLOWED | ENT_XHTML);
|
$text = htmlspecialchars($this->getRecord()->{$contentColumn}, ENT_DISALLOWED | ENT_XHTML);
|
||||||
$proc = iconv_strlen($this->getRecord()->{$contentColumn}) <= OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["processingLimit"];
|
$proc = iconv_strlen($this->getRecord()->{$contentColumn}) <= OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["processingLimit"];
|
||||||
if($html) {
|
if ($html) {
|
||||||
if($proc) {
|
if ($proc) {
|
||||||
$text = $this->formatLinks($text);
|
$text = $this->formatLinks($text);
|
||||||
$text = preg_replace("%@([A-Za-z0-9]++) \(((?:[\p{L&}\p{Lo} 0-9]\p{Mn}?)++)\)%Xu", "[$1|$2]", $text);
|
$text = preg_replace("%@([A-Za-z0-9]++) \(((?:[\p{L&}\p{Lo} 0-9]\p{Mn}?)++)\)%Xu", "[$1|$2]", $text);
|
||||||
$text = preg_replace("%([\n\r\s]|^)(@([A-Za-z0-9]++))%Xu", "$1[$3|@$3]", $text);
|
$text = preg_replace("%([\n\r\s]|^)(@([A-Za-z0-9]++))%Xu", "$1[$3|@$3]", $text);
|
||||||
$text = preg_replace("%\[([A-Za-z0-9]++)\|((?:[\p{L&}\p{Lo} 0-9@]\p{Mn}?)++)\]%Xu", "<a href='/$1'>$2</a>", $text);
|
$text = preg_replace("%\[([A-Za-z0-9]++)\|((?:[\p{L&}\p{Lo} 0-9@]\p{Mn}?)++)\]%Xu", "<a href='/$1'>$2</a>", $text);
|
||||||
$text = preg_replace_callback("%([\n\r\s]|^)(\#([\p{L}_0-9][\p{L}_0-9\(\)\-\']+[\p{L}_0-9\(\)]|[\p{L}_0-9]{1,2}))%Xu", function($m) {
|
$text = preg_replace_callback("%([\n\r\s]|^)(\#([\p{L}_0-9][\p{L}_0-9\(\)\-\']+[\p{L}_0-9\(\)]|[\p{L}_0-9]{1,2}))%Xu", function ($m) {
|
||||||
$slug = rawurlencode($m[3]);
|
$slug = rawurlencode($m[3]);
|
||||||
|
|
||||||
return "$m[1]<a href='/search?section=posts&q=%23$slug'>$m[2]</a>";
|
return "$m[1]<a href='/search?section=posts&q=%23$slug'>$m[2]</a>";
|
||||||
}, $text);
|
}, $text);
|
||||||
|
|
||||||
$text = $this->formatEmojis($text);
|
$text = $this->formatEmojis($text);
|
||||||
}
|
}
|
||||||
|
|
||||||
$text = $this->removeZalgo($text);
|
$text = $this->removeZalgo($text);
|
||||||
$text = nl2br($text);
|
$text = nl2br($text);
|
||||||
} else {
|
} else {
|
||||||
$text = str_replace("\r\n","\n", $text);
|
$text = str_replace("\r\n", "\n", $text);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["christian"])
|
if (OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["christian"]) {
|
||||||
ObsceneCensorRus::filterText($text);
|
ObsceneCensorRus::filterText($text);
|
||||||
|
}
|
||||||
|
|
||||||
return $text;
|
return $text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace openvk\Web\Models\Entities\Traits;
|
namespace openvk\Web\Models\Entities\Traits;
|
||||||
|
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
use openvk\Web\Models\Repositories\Users;
|
use openvk\Web\Models\Repositories\Users;
|
||||||
use Chandler\Database\DatabaseConnection;
|
use Chandler\Database\DatabaseConnection;
|
||||||
|
@ -12,16 +16,16 @@ trait TSubscribable
|
||||||
"model" => static::class,
|
"model" => static::class,
|
||||||
"target" => $this->getId(),
|
"target" => $this->getId(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
foreach($subs as $sub) {
|
foreach($subs as $sub) {
|
||||||
$sub = (new Users)->get($sub->follower);
|
$sub = (new Users)->get($sub->follower);
|
||||||
if(!$sub) continue;
|
if(!$sub) continue;
|
||||||
|
|
||||||
yield $sub;
|
yield $sub;
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
function toggleSubscription(User $user): bool
|
public function toggleSubscription(User $user): bool
|
||||||
{
|
{
|
||||||
$ctx = DatabaseConnection::i()->getContext();
|
$ctx = DatabaseConnection::i()->getContext();
|
||||||
$data = [
|
$data = [
|
||||||
|
@ -30,17 +34,17 @@ trait TSubscribable
|
||||||
"target" => $this->getId(),
|
"target" => $this->getId(),
|
||||||
];
|
];
|
||||||
$sub = $ctx->table("subscriptions")->where($data);
|
$sub = $ctx->table("subscriptions")->where($data);
|
||||||
|
|
||||||
if(!($sub->fetch())) {
|
if (!($sub->fetch())) {
|
||||||
$ctx->table("subscriptions")->insert($data);
|
$ctx->table("subscriptions")->insert($data);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sub->delete();
|
$sub->delete();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeFlags(User $user, int $flags, bool $reverse): bool
|
public function changeFlags(User $user, int $flags, bool $reverse): bool
|
||||||
{
|
{
|
||||||
$ctx = DatabaseConnection::i()->getContext();
|
$ctx = DatabaseConnection::i()->getContext();
|
||||||
$data = [
|
$data = [
|
||||||
|
@ -51,12 +55,13 @@ trait TSubscribable
|
||||||
$sub = $ctx->table("subscriptions")->where($data);
|
$sub = $ctx->table("subscriptions")->where($data);
|
||||||
|
|
||||||
bdump($data);
|
bdump($data);
|
||||||
|
|
||||||
if (!$sub)
|
if (!$sub) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$sub->update([
|
$sub->update([
|
||||||
'flags' => $flags
|
'flags' => $flags,
|
||||||
]);
|
]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue