diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 00000000..c284acc9 --- /dev/null +++ b/.github/workflows/lint.yaml @@ -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 diff --git a/.gitignore b/.gitignore index 78f62184..f133ea75 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,5 @@ themepacks/* storage/* !storage/.gitkeep -.idea \ No newline at end of file +.idea +.php-cs-fixer.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 00000000..9c73a61b --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,14 @@ +in(__DIR__) +; + +return (new PhpCsFixer\Config()) + ->setRules([ + '@PER-CS2.0' => true, + '@PHP82Migration' => true, + ]) + ->setFinder($finder) + ->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect()) +; diff --git a/CLI/FetchToncoinTransactions.php b/CLI/FetchToncoinTransactions.php index b4e66dcb..9de2c998 100755 --- a/CLI/FetchToncoinTransactions.php +++ b/CLI/FetchToncoinTransactions.php @@ -1,103 +1,107 @@ -transactions = DatabaseConnection::i()->getContext()->table("cryptotransactions"); - - parent::__construct(); - } - - protected function configure(): void - { - $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 execute(InputInterface $input, OutputInterface $output): int - { - $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; - } - - $testnetSubdomain = OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["testnet"] ? "testnet." : ""; - $url = "https://" . $testnetSubdomain . "toncenter.com/api/v2/getTransactions?"; - - $opts = [ - "http" => [ - "method" => "GET", - "header" => "Accept: application/json" - ] - ]; - - $selection = $this->transactions->select('hash, lt')->order("id DESC")->limit(1)->fetch(); - $trHash = $selection->hash ?? NULL; - $trLt = $selection->lt ?? NULL; - - $data = http_build_query([ - "address" => OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["address"], - "limit" => 100, - "hash" => $trHash, - "to_lt" => $trLt - ]); - - $response = file_get_contents($url . $data, false, stream_context_create($opts)); - $response = json_decode($response, true); - - $header->writeln("Gonna up the balance of users"); - foreach($response["result"] as $transfer) { - $outputArray; - preg_match('/' . OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["regex"] . '/', $transfer["in_msg"]["message"], $outputArray); - $userId = ctype_digit($outputArray[1]) ? intval($outputArray[1]) : NULL; - if(is_null($userId)) { - $header->writeln("Well, that's a donation. Thanks! XD"); - } else { - $user = (new Users)->get($userId); - if(!$user) { - $header->writeln("Well, that's a donation. Thanks! XD"); - } else { - $value = ($transfer["in_msg"]["value"] / NANOTON) / OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["rate"]; - $user->setCoins($user->getCoins() + $value); - $user->save(); - (new CoinsTransferNotification($user, (new Users)->get(OPENVK_ROOT_CONF["openvk"]["preferences"]["support"]["adminAccount"]), (int) $value, "Via TON cryptocurrency"))->emit(); - $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; - } -} \ No newline at end of file +transactions = DatabaseConnection::i()->getContext()->table("cryptotransactions"); + + parent::__construct(); + } + + protected function configure(): void + { + $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 execute(InputInterface $input, OutputInterface $output): int + { + $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; + } + + $testnetSubdomain = OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["testnet"] ? "testnet." : ""; + $url = "https://" . $testnetSubdomain . "toncenter.com/api/v2/getTransactions?"; + + $opts = [ + "http" => [ + "method" => "GET", + "header" => "Accept: application/json", + ], + ]; + + $selection = $this->transactions->select('hash, lt')->order("id DESC")->limit(1)->fetch(); + $trHash = $selection->hash ?? null; + $trLt = $selection->lt ?? null; + + $data = http_build_query([ + "address" => OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["address"], + "limit" => 100, + "hash" => $trHash, + "to_lt" => $trLt, + ]); + + $response = file_get_contents($url . $data, false, stream_context_create($opts)); + $response = json_decode($response, true); + + $header->writeln("Gonna up the balance of users"); + foreach ($response["result"] as $transfer) { + $outputArray; + preg_match('/' . OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["regex"] . '/', $transfer["in_msg"]["message"], $outputArray); + $userId = ctype_digit($outputArray[1]) ? intval($outputArray[1]) : null; + if (is_null($userId)) { + $header->writeln("Well, that's a donation. Thanks! XD"); + } else { + $user = (new Users())->get($userId); + if (!$user) { + $header->writeln("Well, that's a donation. Thanks! XD"); + } else { + $value = ($transfer["in_msg"]["value"] / NANOTON) / OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["rate"]; + $user->setCoins($user->getCoins() + $value); + $user->save(); + (new CoinsTransferNotification($user, (new Users())->get(OPENVK_ROOT_CONF["openvk"]["preferences"]["support"]["adminAccount"]), (int) $value, "Via TON cryptocurrency"))->emit(); + $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; + } +} diff --git a/CLI/RebuildImagesCommand.php b/CLI/RebuildImagesCommand.php index 937978b1..cbc9e49c 100644 --- a/CLI/RebuildImagesCommand.php +++ b/CLI/RebuildImagesCommand.php @@ -1,5 +1,9 @@ -images = DatabaseConnection::i()->getContext()->table("photos"); @@ -40,8 +44,9 @@ class RebuildImagesCommand extends Command ]); $filter = ["deleted" => false]; - if($input->getOption("upgrade-only")) - $filter["sizes"] = NULL; + if ($input->getOption("upgrade-only")) { + $filter["sizes"] = null; + } $selection = $this->images->select("id")->where($filter); $totalPics = $selection->count(); @@ -52,24 +57,25 @@ class RebuildImagesCommand extends Command $errors = 0; $count = 0; - $avgTime = NULL; + $avgTime = null; $begin = new \DateTimeImmutable("now"); - foreach($selection as $idHolder) { + foreach ($selection as $idHolder) { $start = microtime(true); try { - $photo = (new Photos)->get($idHolder->id); + $photo = (new Photos())->get($idHolder->id); $photo->getSizes(true, true); $photo->getDimensions(); - } catch(ImageException $ex) { + } catch (ImageException $ex) { $errors++; } $timeConsumed = microtime(true) - $start; - if(!$avgTime) + if (!$avgTime) { $avgTime = $timeConsumed; - else + } else { $avgTime = ($avgTime + $timeConsumed) / 2; + } $eta = $begin->getTimestamp() + ceil($totalPics * $avgTime); $int = (new \DateTimeImmutable("now"))->diff(new \DateTimeImmutable("@$eta")); @@ -83,4 +89,4 @@ class RebuildImagesCommand extends Command return Command::SUCCESS; } -} \ No newline at end of file +} diff --git a/CODE_STYLE.md b/CODE_STYLE.md deleted file mode 100644 index 85f5ab74..00000000 --- a/CODE_STYLE.md +++ /dev/null @@ -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 `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"; -} -``` diff --git a/DBEntity.updated.php b/DBEntity.updated.php index 4c039b54..342d7363 100644 --- a/DBEntity.updated.php +++ b/DBEntity.updated.php @@ -1,5 +1,9 @@ -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); + } $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)); $this->stateChanges($field, $args[0]); } else { @@ -50,38 +57,40 @@ abstract class DBEntity protected function stateChanges(string $column, $value): void { - if(!is_null($this->record)) - $t = $this->record->{$column}; #Test if column exists + if (!is_null($this->record)) { + $t = $this->record->{$column}; + } #Test if column exists $this->changes[$column] = $value; } - function getId() + public function getId() { return $this->getRecord()->id; } - function isDeleted(): bool + public function isDeleted(): bool { return (bool) $this->getRecord()->deleted; } - function unwrap(): object + public function unwrap(): object { return (object) $this->getRecord()->toArray(); } - function delete(bool $softly = true): void + public function delete(bool $softly = true): void { $user = CurrentUser::i()->getUser(); $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?"); + } - (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]); } else { $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?"); + } $user = CurrentUser::i()->getUser(); $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]); } - function save(?bool $log = true): void + public function save(?bool $log = true): void { if ($log) { $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); 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 { 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) { - $this->record = $this->getTable()->insert((array)$this->record); + $this->record = $this->getTable()->insert((array) $this->record); } else { $this->getTable()->get($this->record->id)->update($this->changes); $this->record = $this->getTable()->get($this->record->id); @@ -131,10 +141,8 @@ abstract class DBEntity $this->changes = []; } - function getTableName(): string + public function getTableName(): string { return $this->getTable()->getName(); } - - use \Nette\SmartObject; } diff --git a/ServiceAPI/Apps.php b/ServiceAPI/Apps.php index a09dc49f..16f59636 100644 --- a/ServiceAPI/Apps.php +++ b/ServiceAPI/Apps.php @@ -1,4 +1,7 @@ -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()); $sign = hash_hmac("sha512/224", $hexId, CHANDLER_ROOT_CONF["security"]["secret"], true); $marketingId = $hexId . "_" . base64_encode($sign); - + $resolve([ "id" => $this->user->getId(), "marketing_id" => $marketingId, @@ -35,82 +38,84 @@ class Apps implements Handler "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); - 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()) { + if (!$app || !$app->isEnabled()) { $reject("No application with this id found"); 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"); return; } - + $coinsLeft = $this->user->getCoins() - $amount; - if($coinsLeft < 0) { + if ($coinsLeft < 0) { $reject(41, "Not enough money"); return; } - + $this->user->setCoins($coinsLeft); $this->user->save(); $app->addCoins($amount); - + $t = time(); $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); - if(!$app) { + if (!$app) { $reject("No application with this id found"); 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"); return; } - + $coins = $app->getBalance(); $app->withdrawCoins(); $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; - if($acceptsStale) - $token = (new APITokens)->getStaleByUser($this->user->getId(), $clientName); - - if(is_null($token)) { + if ($acceptsStale) { + $token = (new APITokens())->getStaleByUser($this->user->getId(), $clientName); + } + + if (is_null($token)) { $stale = false; - $token = new APIToken; + $token = new APIToken(); $token->setUser($this->user); $token->setPlatform($clientName ?? (new WhichBrowser\Parser(getallheaders()))->toString()); $token->save(); } - + $resolve([ 'is_stale' => $stale, 'token' => $token->getFormattedToken(), ]); } -} \ No newline at end of file +} diff --git a/ServiceAPI/Groups.php b/ServiceAPI/Groups.php index 9eed0e8d..b9662e60 100644 --- a/ServiceAPI/Groups.php +++ b/ServiceAPI/Groups.php @@ -1,5 +1,9 @@ -user = $user; - $this->groups = new Clubs; + $this->groups = new Clubs(); } - - function getWriteableClubs(callable $resolve, callable $reject) + + public function getWriteableClubs(callable $resolve, callable $reject) { $clubs = []; $wclubs = $this->groups->getWriteableClubs($this->user->getId()); $count = $this->groups->getWriteableClubsCount($this->user->getId()); - if(!$count) { + if (!$count) { $reject("You don't have any groups with write access"); return; } - foreach($wclubs as $club) { + foreach ($wclubs as $club) { $clubs[] = [ "name" => $club->getName(), "id" => $club->getId(), - "avatar" => $club->getAvatarUrl() # если в овк когда-нибудь появится крутой список с аватарками, то можно использовать это поле + "avatar" => $club->getAvatarUrl(), # если в овк когда-нибудь появится крутой список с аватарками, то можно использовать это поле ]; } diff --git a/ServiceAPI/Handler.php b/ServiceAPI/Handler.php index 7b19d6b6..a1711298 100644 --- a/ServiceAPI/Handler.php +++ b/ServiceAPI/Handler.php @@ -1,8 +1,12 @@ -user = $user; } - function resolve(int $id, callable $resolve, callable $reject): void + public function resolve(int $id, callable $resolve, callable $reject): void { - if($id > 0) { - $user = (new Users)->get($id); - if(!$user) { + if ($id > 0) { + $user = (new Users())->get($id); + if (!$user) { $reject("Not found"); return; } @@ -32,8 +36,8 @@ class Mentions implements Handler return; } - $club = (new Clubs)->get(abs($id)); - if(!$club) { + $club = (new Clubs())->get(abs($id)); + if (!$club) { $reject("Not found"); return; } diff --git a/ServiceAPI/Notes.php b/ServiceAPI/Notes.php index ea76267e..67e78dfd 100644 --- a/ServiceAPI/Notes.php +++ b/ServiceAPI/Notes.php @@ -1,6 +1,7 @@ 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); - if(!$note || $note->isDeleted()) + if (!$note || $note->isDeleted()) { $reject(83, "Note is gone"); - + } + $noteOwner = $note->getOwner(); 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"); + } - if(!$note->canBeViewedBy($this->user)) + if (!$note->canBeViewedBy($this->user)) { $reject(15, "Access to note denied"); - + } + $resolve([ "title" => $note->getName(), "link" => "/note" . $note->getPrettyId(), diff --git a/ServiceAPI/Notifications.php b/ServiceAPI/Notifications.php index 12f0ed8e..b78486e2 100644 --- a/ServiceAPI/Notifications.php +++ b/ServiceAPI/Notifications.php @@ -1,5 +1,9 @@ -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->save(); $resolve("OK"); } - - function fetch(callable $resolve, callable $reject): void + + public function fetch(callable $resolve, callable $reject): void { $kafkaConf = OPENVK_ROOT_CONF["openvk"]["credentials"]["notificationsBroker"]; - if(!$kafkaConf["enable"]) { + if (!$kafkaConf["enable"]) { $reject(1999, "Disabled"); return; } - + $kafkaConf = $kafkaConf["kafka"]; $conf = new RDKConf(); $conf->set("metadata.broker.list", $kafkaConf["addr"] . ":" . $kafkaConf["port"]); $conf->set("group.id", "UserFetch-" . $this->user->getId()); # Чтобы уведы приходили только на разные устройства одного чебупелика $conf->set("auto.offset.reset", "latest"); - + set_time_limit(30); $consumer = new KafkaConsumer($conf); $consumer->subscribe([ $kafkaConf["topic"] ]); - - while(true) { - $message = $consumer->consume(30*1000); + + while (true) { + $message = $consumer->consume(30 * 1000); switch ($message->err) { case RD_KAFKA_RESP_ERR_NO_ERROR: $descriptor = $message->payload; [,$user,] = explode(",", $descriptor); - if(((int) $user) === $this->user->getId()) { + if (((int) $user) === $this->user->getId()) { $data = (object) []; $notification = $this->notifs->fromDescriptor($descriptor, $data); - if(!$notification) { + if (!$notification) { $reject(1982, "Server Error"); return; } - + $tplDir = __DIR__ . "/../Web/Presenters/templates/components/notifications/"; $tplId = "$tplDir$data->actionCode/_$data->originModelType" . "_" . $data->targetModelType . "_.xml"; - $latte = new TemplatingEngine; + $latte = new TemplatingEngine(); $latte->setTempDirectory(CHANDLER_ROOT . "/tmp/cache/templates"); $latte->addFilter("translate", fn($trId) => tr($trId)); $resolve([ @@ -68,7 +72,7 @@ class Notifications implements Handler ]); return; } - + break; case RD_KAFKA_RESP_ERR__TIMED_OUT: case RD_KAFKA_RESP_ERR__PARTITION_EOF: diff --git a/ServiceAPI/Polls.php b/ServiceAPI/Polls.php index 9d3e2e7f..885cc9e1 100644 --- a/ServiceAPI/Polls.php +++ b/ServiceAPI/Polls.php @@ -1,5 +1,9 @@ -user = $user; - $this->polls = new PollRepo; + $this->polls = new PollRepo(); } - + private function getPollHtml(int $poll): string { 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); - if(!$poll) { + if (!$poll) { $reject("Poll not found"); return; } - + try { $options = explode(",", $options); $poll->vote($this->user, $options); - } catch(AlreadyVotedException $ex) { + } catch (AlreadyVotedException $ex) { $reject("Poll state changed: user has already voted."); return; - } catch(PollLockedException $ex) { + } catch (PollLockedException $ex) { $reject("Poll state changed: poll has ended."); return; - } catch(InvalidOptionException $ex) { + } catch (InvalidOptionException $ex) { $reject("Foreign options passed."); return; - } catch(UnexpectedValueException $ex) { + } catch (UnexpectedValueException $ex) { $reject("Too much options passed."); return; } - + $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); - if(!$poll) { + if (!$poll) { $reject("Poll not found"); return; } - + try { $poll->revokeVote($this->user); - } catch(PollLockedException $ex) { + } catch (PollLockedException $ex) { $reject("Votes can't be revoked from this poll."); return; } - + $resolve(["html" => $this->getPollHtml($pollId)]); } -} \ No newline at end of file +} diff --git a/ServiceAPI/Service.php b/ServiceAPI/Service.php index 0c024925..990b958d 100644 --- a/ServiceAPI/Service.php +++ b/ServiceAPI/Service.php @@ -1,23 +1,27 @@ -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); } diff --git a/ServiceAPI/Wall.php b/ServiceAPI/Wall.php index ed7251ac..4066d4f3 100644 --- a/ServiceAPI/Wall.php +++ b/ServiceAPI/Wall.php @@ -1,5 +1,9 @@ -user = $user; - $this->posts = new Posts; - $this->notes = new Notes; - $this->videos = new Videos; + $this->posts = new Posts(); + $this->notes = new Notes(); + $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); - if(!$post || $post->isDeleted()) + if (!$post || $post->isDeleted()) { $reject(53, "No post with id=$id"); + } - if($post->getSuggestionType() != 0) + if ($post->getSuggestionType() != 0) { $reject(25, "Can't get suggested post"); - - if(!$post->canBeViewedBy($this->user)) + } + + if (!$post->canBeViewedBy($this->user)) { $reject(12, "Access denied"); + } $res = (object) []; $res->id = $post->getId(); @@ -36,21 +43,22 @@ class Wall implements Handler $res->author = (($owner = $post->getOwner())) instanceof User ? ($owner->getId()) : ($owner->getId() * -1); - - if($post->isSigned()) + + if ($post->isSigned()) { $res->signedOffBy = $post->getOwnerPost(); - + } + $res->pinned = $post->isPinned(); $res->sponsored = $post->isAd(); $res->nsfw = $post->isExplicit(); $res->text = $post->getText(); - + $res->likes = [ "count" => $post->getLikesCount(), "hasLike" => $post->hasLikeFrom($this->user), "likedBy" => [], ]; - foreach($post->getLikers() as $liker) { + foreach ($post->getLikers() as $liker) { $res->likes["likedBy"][] = [ "id" => $liker->getId(), "url" => $liker->getURL(), @@ -58,17 +66,17 @@ class Wall implements Handler "avatar" => $liker->getAvatarURL(), ]; } - + $res->created = (string) $post->getPublicationTime(); $res->canPin = $post->canBePinnedBy($this->user); $res->canEdit = $res->canDelete = $post->canBeDeletedBy($this->user); - + $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->setWall($this->user->getId()); $post->setCreated(time()); @@ -77,7 +85,7 @@ class Wall implements Handler $post->setFlags(0); $post->setNsfw(false); $post->save(); - + $resolve($post->getId()); } } diff --git a/VKAPI/Exceptions/APIErrorException.php b/VKAPI/Exceptions/APIErrorException.php index c570e0e9..f5e44f63 100644 --- a/VKAPI/Exceptions/APIErrorException.php +++ b/VKAPI/Exceptions/APIErrorException.php @@ -1,5 +1,7 @@ -requireUser(); $user = $this->getUser(); @@ -29,13 +33,14 @@ final class Account extends VKAPIRequestHandler ]; $audio_status = $user->getCurrentAudioStatus(); - if(!is_null($audio_status)) + if (!is_null($audio_status)) { $return_object->audio_status = $audio_status->toVkApiStruct($user); + } return $return_object; } - function getInfo(): object + public function getInfo(): object { $this->requireUser(); @@ -50,58 +55,58 @@ final class Account extends VKAPIRequestHandler "is_new_live_streaming_enabled" => false, "lang" => 1, "no_wall_replies" => 0, - "own_posts_default" => 0 + "own_posts_default" => 0, ]; } - function setOnline(): int + public function setOnline(): int { $this->requireUser(); $this->getUser()->updOnline($this->getPlatform()); - + return 1; } - function setOffline(): int + public function setOffline(): int { $this->requireUser(); # Цiй метод є заглушка - + return 1; } - function getAppPermissions(): int + public function getAppPermissions(): int { return 9355263; } - function getCounters(string $filter = ""): object + public function getCounters(string $filter = ""): object { $this->requireUser(); - + return (object) [ "friends" => $this->getUser()->getFollowersCount(), "notifications" => $this->getUser()->getNotificationsCount(), - "messages" => $this->getUser()->getUnreadMessagesCount() + "messages" => $this->getUser()->getUnreadMessagesCount(), ]; # 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->willExecuteWriteAction(); - + $user = $this->getUser(); $output = [ "changed" => 0, ]; - if(!empty($first_name) || !empty($last_name)) { + if (!empty($first_name) || !empty($last_name)) { $output["name_request"] = [ "id" => random_int(1, 2048), # For compatibility with original VK API "status" => "success", @@ -110,37 +115,44 @@ final class Account extends VKAPIRequestHandler ]; try { - if(!empty($first_name)) + if (!empty($first_name)) { $user->setFirst_name($first_name); - if(!empty($last_name)) + } + if (!empty($last_name)) { $user->setLast_Name($last_name); + } } catch (InvalidUserNameException $e) { $output["name_request"]["status"] = "declined"; return (object) $output; } } - if(!empty($screen_name)) - if (!$user->setShortCode($screen_name)) + if (!empty($screen_name)) { + if (!$user->setShortCode($screen_name)) { $this->fail(1260, "Invalid screen name"); + } + } # For compatibility with original VK API - if($sex > 0) + if ($sex > 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); - if (!is_int($birthday)) + if (!is_int($birthday)) { $this->fail(100, "invalid value of bdate."); + } $user->setBirthday($birthday); } # For compatibility with original VK API - switch($bdate_visibility) { + switch ($bdate_visibility) { case 0: $this->fail(946, "Hiding date of birth is not implemented."); break; @@ -150,14 +162,16 @@ final class Account extends VKAPIRequestHandler case 2: $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); - - 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; $user->save(); } @@ -165,21 +179,22 @@ final class Account extends VKAPIRequestHandler return (object) $output; } - function getBalance(): object + public function getBalance(): object { $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"); - + } + return (object) ['votes' => $this->getUser()->getCoins()]; } - function getOvkSettings(): object + public function getOvkSettings(): object { $this->requireUser(); $user = $this->getUser(); - $settings_list = (object)[ + $settings_list = (object) [ 'avatar_style' => $user->getStyleAvatar(), 'style' => $user->getStyle(), 'show_rating' => !$user->prefersNotToSeeRating(), @@ -191,32 +206,39 @@ final class Account extends VKAPIRequestHandler 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->willExecuteWriteAction(); - if(!OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"]) + if (!OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"]) { $this->fail(-105, "Commerce is disabled on this instance"); + } - if($receiver < 0) + if ($receiver < 0) { $this->fail(-248, "Invalid receiver id"); + } - if($value < 1) + if ($value < 1) { $this->fail(-248, "Invalid value"); + } - if(iconv_strlen($message) > 255) + if (iconv_strlen($message) > 255) { $this->fail(-249, "Message is too long"); + } - if($this->getUser()->getCoins() < $value) + if ($this->getUser()->getCoins() < $value) { $this->fail(-252, "Not enough votes"); + } - $receiver_entity = (new \openvk\Web\Models\Repositories\Users)->get($receiver); - if(!$receiver_entity || $receiver_entity->isDeleted() || !$receiver_entity->canBeViewedBy($this->getUser())) + $receiver_entity = (new \openvk\Web\Models\Repositories\Users())->get($receiver); + if (!$receiver_entity || $receiver_entity->isDeleted() || !$receiver_entity->canBeViewedBy($this->getUser())) { $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->getUser()->setCoins($this->getUser()->getCoins() - $value); $this->getUser()->save(); @@ -229,116 +251,126 @@ final class Account extends VKAPIRequestHandler return (object) ['votes' => $this->getUser()->getCoins()]; } - function ban(int $owner_id): int + public function ban(int $owner_id): int { $this->requireUser(); $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"); + } $config_limit = OPENVK_ROOT_CONF['openvk']['preferences']['blacklists']['limit'] ?? 100; $user_blocks = $this->getUser()->getBlacklistSize(); - if(($user_blocks + 1) > $config_limit) + if (($user_blocks + 1) > $config_limit) { $this->fail(-7856, "Blacklist limit exceeded"); + } $entity = get_entity_by_id($owner_id); - if(!$entity || $entity->isDeleted()) + if (!$entity || $entity->isDeleted()) { return 0; + } - if($entity->isBlacklistedBy($this->getUser())) + if ($entity->isBlacklistedBy($this->getUser())) { return 1; + } $this->getUser()->addToBlacklist($entity); return 1; } - function unban(int $owner_id): int + public function unban(int $owner_id): int { $this->requireUser(); $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()) { + return 1; + } $entity = get_entity_by_id($owner_id); - if(!$entity) + if (!$entity) { return 0; + } - if(!$entity->isBlacklistedBy($this->getUser())) + if (!$entity->isBlacklistedBy($this->getUser())) { return 1; + } $this->getUser()->removeFromBlacklist($entity); 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(); - $result = (object)[ + $result = (object) [ 'count' => $this->getUser()->getBlacklistSize(), 'items' => [], ]; $banned = $this->getUser()->getBlacklist($offset, $count); - foreach($banned as $ban) { - if(!$ban) continue; + foreach ($banned as $ban) { + if (!$ban) { + continue; + } $result->items[] = $ban->toVkApiStruct($this->getUser(), $fields); } - + return $result; } - function saveInterestsInfo( - string $interests = NULL, - string $fav_music = NULL, - string $fav_films = NULL, - string $fav_shows = NULL, - string $fav_books = NULL, - string $fav_quote = NULL, - string $fav_games = NULL, - string $about = NULL, - ) - { + public function saveInterestsInfo( + string $interests = null, + string $fav_music = null, + string $fav_films = null, + string $fav_shows = null, + string $fav_books = null, + string $fav_quote = null, + string $fav_games = null, + string $about = null, + ) { $this->requireUser(); $this->willExecuteWriteAction(); $user = $this->getUser(); $changes = 0; $changes_array = [ - "interests" => $interests, - "fav_music" => $fav_music, - "fav_films" => $fav_films, - "fav_books" => $fav_books, - "fav_shows" => $fav_shows, - "fav_quote" => $fav_quote, - "fav_games" => $fav_games, + "interests" => $interests, + "fav_music" => $fav_music, + "fav_films" => $fav_films, + "fav_books" => $fav_books, + "fav_shows" => $fav_shows, + "fav_quote" => $fav_quote, + "fav_games" => $fav_games, "about" => $about, ]; - foreach($changes_array as $change_name => $change_value) { - $set_name = "set".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()) { + foreach ($changes_array as $change_name => $change_value) { + $set_name = "set" . 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()) { $user->$set_name(ovk_proc_strtr($change_value, 1000)); $changes += 1; } } - if($changes > 0) { + if ($changes > 0) { $user->save(); } return (object) [ - "changed" => (int)($changes > 0), + "changed" => (int) ($changes > 0), ]; } } diff --git a/VKAPI/Handlers/Audio.php b/VKAPI/Handlers/Audio.php index e0991af9..b84475a4 100644 --- a/VKAPI/Handlers/Audio.php +++ b/VKAPI/Handlers/Audio.php @@ -1,5 +1,9 @@ -fail(0404, "Audio not found"); - else if(!$audio->canBeViewedBy($this->getUser())) + if (!$audio) { + $this->fail(0o404, "Audio not found"); + } elseif (!$audio->canBeViewedBy($this->getUser())) { $this->fail(201, "Access denied to audio(" . $audio->getPrettyId() . ")"); + } # рофлан ебало $privApi = $hash && $GLOBALS["csrfCheck"]; $audioObj = $audio->toVkApiStruct($this->getUser()); - if(!$privApi) { + if (!$privApi) { $audioObj->manifest = false; $audioObj->keys = false; } - if($need_user) { - $user = (new \openvk\Web\Models\Repositories\Users)->get($audio->getOwner()->getId()); + if ($need_user) { + $user = (new \openvk\Web\Models\Repositories\Users())->get($audio->getOwner()->getId()); $audioObj->user = (object) [ "id" => $user->getId(), "photo" => $user->getAvatarUrl(), @@ -37,10 +42,10 @@ final class Audio extends VKAPIRequestHandler return $audioObj; } - private function streamToResponse(EntityStream $es, int $offset, int $count, ?string $hash = NULL): object + private function streamToResponse(EntityStream $es, int $offset, int $count, ?string $hash = null): object { $items = []; - foreach($es->offsetLimit($offset, $count) as $audio) { + foreach ($es->offsetLimit($offset, $count) as $audio) { $items[] = $this->toSafeAudioStruct($audio, $hash); } @@ -52,31 +57,34 @@ final class Audio extends VKAPIRequestHandler private function validateGenre(?string& $genre_str, ?int $genre_id): void { - if(!is_null($genre_str)) { - if(!in_array($genre_str, AEntity::genres)) + if (!is_null($genre_str)) { + if (!in_array($genre_str, AEntity::genres)) { $this->fail(8, "Invalid genre_str"); - } else if(!is_null($genre_id)) { - $genre_str = array_flip(AEntity::vkGenres)[$genre_id] ?? NULL; - if(!$genre_str) + } + } elseif (!is_null($genre_id)) { + $genre_str = array_flip(AEntity::vkGenres)[$genre_id] ?? null; + if (!$genre_str) { $this->fail(8, "Invalid genre ID $genre_id"); + } } } private function audioFromAnyId(string $id): ?AEntity { $descriptor = explode("_", $id); - if(sizeof($descriptor) === 1) { - if(ctype_digit($descriptor[0])) { - $audio = (new Audios)->get((int) $descriptor[0]); + if (sizeof($descriptor) === 1) { + if (ctype_digit($descriptor[0])) { + $audio = (new Audios())->get((int) $descriptor[0]); } else { $aid = base64_decode($descriptor[0], true); - if(!$aid) + if (!$aid) { $this->fail(8, "Invalid audio $id"); + } - $audio = (new Audios)->get((int) $aid); + $audio = (new Audios())->get((int) $aid); } - } else if(sizeof($descriptor) === 2) { - $audio = (new Audios)->getByOwnerAndVID((int) $descriptor[0], (int) $descriptor[1]); + } elseif (sizeof($descriptor) === 2) { + $audio = (new Audios())->getByOwnerAndVID((int) $descriptor[0], (int) $descriptor[1]); } else { $this->fail(8, "Invalid audio $id"); } @@ -84,12 +92,12 @@ final class Audio extends VKAPIRequestHandler return $audio; } - function getById(string $audios, ?string $hash = NULL, int $need_user = 0): object + public function getById(string $audios, ?string $hash = null, int $need_user = 0): object { $this->requireUser(); $audioIds = array_unique(explode(",", $audios)); - if(sizeof($audioIds) === 1) { + if (sizeof($audioIds) === 1) { $audio = $this->audioFromAnyId($audioIds[0]); return (object) [ @@ -98,13 +106,14 @@ final class Audio extends VKAPIRequestHandler $this->toSafeAudioStruct($audio, $hash, (bool) $need_user), ], ]; - } else if(sizeof($audioIds) > 6000) { + } elseif (sizeof($audioIds) > 6000) { $this->fail(1980, "Can't get more than 6000 audios at once"); } $audios = []; - foreach($audioIds as $id) + foreach ($audioIds as $id) { $audios[] = $this->getById($id, $hash)->items[0]; + } return (object) [ "count" => sizeof($audios), @@ -112,20 +121,21 @@ final class Audio extends VKAPIRequestHandler ]; } - function isLagtrain(string $audio_id): int + public function isLagtrain(string $audio_id): int { $this->requireUser(); $audio = $this->audioFromAnyId($audio_id); - if(!$audio) - $this->fail(0404, "Audio not found"); + if (!$audio) { + $this->fail(0o404, "Audio not found"); + } # Possible information disclosure risks are acceptable :D return (int) (strpos($audio->getName(), "Lagtrain") !== false); } // TODO stub - function getRecommendations(): object + public function getRecommendations(): object { return (object) [ "count" => 0, @@ -133,61 +143,65 @@ final class Audio extends VKAPIRequestHandler ]; } - function getPopular(?int $genre_id = NULL, ?string $genre_str = NULL, int $offset = 0, int $count = 100, ?string $hash = NULL): object + public function getPopular(?int $genre_id = null, ?string $genre_str = null, int $offset = 0, int $count = 100, ?string $hash = null): object { $this->requireUser(); $this->validateGenre($genre_str, $genre_id); - $results = (new Audios)->getGlobal(Audios::ORDER_POPULAR, $genre_str); + $results = (new Audios())->getGlobal(Audios::ORDER_POPULAR, $genre_str); return $this->streamToResponse($results, $offset, $count, $hash); } - function getFeed(?int $genre_id = NULL, ?string $genre_str = NULL, int $offset = 0, int $count = 100, ?string $hash = NULL): object + public function getFeed(?int $genre_id = null, ?string $genre_str = null, int $offset = 0, int $count = 100, ?string $hash = null): object { $this->requireUser(); $this->validateGenre($genre_str, $genre_id); - $results = (new Audios)->getGlobal(Audios::ORDER_NEW, $genre_str); + $results = (new Audios())->getGlobal(Audios::ORDER_NEW, $genre_str); return $this->streamToResponse($results, $offset, $count, $hash); } - function search(string $q, int $auto_complete = 0, int $lyrics = 0, int $performer_only = 0, int $sort = 2, int $search_own = 0, int $offset = 0, int $count = 30, ?string $hash = NULL): object + public function search(string $q, int $auto_complete = 0, int $lyrics = 0, int $performer_only = 0, int $sort = 2, int $search_own = 0, int $offset = 0, int $count = 30, ?string $hash = null): object { $this->requireUser(); - if(($auto_complete + $search_own) != 0) + if (($auto_complete + $search_own) != 0) { $this->fail(10, "auto_complete and search_own are not supported"); - else if($count > 300 || $count < 1) + } elseif ($count > 300 || $count < 1) { $this->fail(8, "count is invalid: $count"); - - $results = (new Audios)->search($q, $sort, (bool) $performer_only, (bool) $lyrics); - - return $this->streamToResponse($results, $offset, $count, $hash); - } - - function getCount(int $owner_id, int $uploaded_only = 0): int - { - $this->requireUser(); - - if($owner_id < 0) { - $owner_id *= -1; - $group = (new Clubs)->get($owner_id); - if(!$group) - $this->fail(0404, "Group not found"); - - return (new Audios)->getClubCollectionSize($group); } - $user = (new \openvk\Web\Models\Repositories\Users)->get($owner_id); - if(!$user) - $this->fail(0404, "User not found"); + $results = (new Audios())->search($q, $sort, (bool) $performer_only, (bool) $lyrics); - if(!$user->getPrivacyPermission("audios.read", $this->getUser())) + return $this->streamToResponse($results, $offset, $count, $hash); + } + + public function getCount(int $owner_id, int $uploaded_only = 0): int + { + $this->requireUser(); + + if ($owner_id < 0) { + $owner_id *= -1; + $group = (new Clubs())->get($owner_id); + if (!$group) { + $this->fail(0o404, "Group not found"); + } + + return (new Audios())->getClubCollectionSize($group); + } + + $user = (new \openvk\Web\Models\Repositories\Users())->get($owner_id); + if (!$user) { + $this->fail(0o404, "User not found"); + } + + if (!$user->getPrivacyPermission("audios.read", $this->getUser())) { $this->fail(15, "Access denied"); + } - if($uploaded_only) { + if ($uploaded_only) { return DatabaseConnection::i()->getContext()->table("audios") ->where([ "deleted" => false, @@ -195,18 +209,18 @@ final class Audio extends VKAPIRequestHandler ])->count(); } - return (new Audios)->getUserCollectionSize($user); + return (new Audios())->getUserCollectionSize($user); } - function get(int $owner_id = 0, int $album_id = 0, string $audio_ids = '', int $need_user = 1, int $offset = 0, int $count = 100, int $uploaded_only = 0, int $need_seed = 0, ?string $shuffle_seed = NULL, int $shuffle = 0, ?string $hash = NULL): object - { - $this->requireUser(); + public function get(int $owner_id = 0, int $album_id = 0, string $audio_ids = '', int $need_user = 1, int $offset = 0, int $count = 100, int $uploaded_only = 0, int $need_seed = 0, ?string $shuffle_seed = null, int $shuffle = 0, ?string $hash = null): object + { + $this->requireUser(); - $shuffleSeed = NULL; - $shuffleSeedStr = NULL; - if($shuffle == 1) { - if(!$shuffle_seed) { - if($need_seed == 1) { + $shuffleSeed = null; + $shuffleSeedStr = null; + if ($shuffle == 1) { + if (!$shuffle_seed) { + if ($need_seed == 1) { $shuffleSeed = openssl_random_pseudo_bytes(6); $shuffleSeedStr = base64_encode($shuffleSeed); $shuffleSeed = hexdec(bin2hex($shuffleSeed)); @@ -222,74 +236,85 @@ final class Audio extends VKAPIRequestHandler } } - if($album_id != 0) { - $album = (new Audios)->getPlaylist($album_id); - if(!$album) - $this->fail(0404, "album_id invalid"); - else if(!$album->canBeViewedBy($this->getUser())) + if ($album_id != 0) { + $album = (new Audios())->getPlaylist($album_id); + if (!$album) { + $this->fail(0o404, "album_id invalid"); + } elseif (!$album->canBeViewedBy($this->getUser())) { $this->fail(600, "Can't open this album for reading"); + } $songs = []; $list = $album->getAudios($offset, $count, $shuffleSeed); - foreach($list as $song) + foreach ($list as $song) { $songs[] = $this->toSafeAudioStruct($song, $hash, $need_user == 1); + } $response = (object) [ "count" => sizeof($songs), "items" => $songs, ]; - if(!is_null($shuffleSeed)) + if (!is_null($shuffleSeed)) { $response->shuffle_seed = $shuffleSeedStr; + } return $response; } - if(!empty($audio_ids)) { + if (!empty($audio_ids)) { $audio_ids = explode(",", $audio_ids); - if(!$audio_ids) + if (!$audio_ids) { $this->fail(10, "Audio::get@L0d186:explode(string): Unknown error"); - else if(sizeof($audio_ids) < 1) + } elseif (sizeof($audio_ids) < 1) { $this->fail(8, "Invalid audio_ids syntax"); + } - if(!is_null($shuffleSeed)) + if (!is_null($shuffleSeed)) { $audio_ids = knuth_shuffle($audio_ids, $shuffleSeed); + } $obj = $this->getById(implode(",", $audio_ids), $hash, $need_user); - if(!is_null($shuffleSeed)) + if (!is_null($shuffleSeed)) { $obj->shuffle_seed = $shuffleSeedStr; + } return $obj; } $dbCtx = DatabaseConnection::i()->getContext(); - if($uploaded_only == 1) { - if($owner_id <= 0) + if ($uploaded_only == 1) { + if ($owner_id <= 0) { $this->fail(8, "uploaded_only can only be used with owner_id > 0"); + } - $user = (new \openvk\Web\Models\Repositories\Users)->get($owner_id); + $user = (new \openvk\Web\Models\Repositories\Users())->get($owner_id); - if(!$user) - $this->fail(0602, "Invalid user"); + if (!$user) { + $this->fail(0o602, "Invalid user"); + } - if(!$user->getPrivacyPermission("audios.read", $this->getUser())) + if (!$user->getPrivacyPermission("audios.read", $this->getUser())) { $this->fail(15, "Access denied: this user chose to hide his audios"); + } - if(!is_null($shuffleSeed)) { + if (!is_null($shuffleSeed)) { $audio_ids = []; $query = $dbCtx->table("audios")->select("virtual_id")->where([ "owner" => $owner_id, "deleted" => 0, ]); - foreach($query as $res) + foreach ($query as $res) { $audio_ids[] = $res->virtual_id; + } $audio_ids = knuth_shuffle($audio_ids, $shuffleSeed); $audio_ids = array_slice($audio_ids, $offset, $count); $audio_q = ""; # audio.getById query - foreach($audio_ids as $aid) + foreach ($audio_ids as $aid) { $audio_q .= ",$owner_id" . "_$aid"; + } $obj = $this->getById(substr($audio_q, 1), $hash, $need_user); $obj->shuffle_seed = $shuffleSeedStr; @@ -297,22 +322,24 @@ final class Audio extends VKAPIRequestHandler return $obj; } - $res = (new Audios)->getByUploader((new \openvk\Web\Models\Repositories\Users)->get($owner_id)); + $res = (new Audios())->getByUploader((new \openvk\Web\Models\Repositories\Users())->get($owner_id)); return $this->streamToResponse($res, $offset, $count, $hash, $need_user); } $query = $dbCtx->table("audio_relations")->select("audio")->where("entity", $owner_id); - if(!is_null($shuffleSeed)) { + if (!is_null($shuffleSeed)) { $audio_ids = []; - foreach($query as $aid) + foreach ($query as $aid) { $audio_ids[] = $aid->audio; + } $audio_ids = knuth_shuffle($audio_ids, $shuffleSeed); $audio_ids = array_slice($audio_ids, $offset, $count); $audio_q = ""; - foreach($audio_ids as $aid) + foreach ($audio_ids as $aid) { $audio_q .= ",$aid"; + } $obj = $this->getById(substr($audio_q, 1), $hash, $need_user); $obj->shuffle_seed = $shuffleSeedStr; @@ -322,36 +349,41 @@ final class Audio extends VKAPIRequestHandler $items = []; - if($owner_id > 0) { - $user = (new \openvk\Web\Models\Repositories\Users)->get($owner_id); + if ($owner_id > 0) { + $user = (new \openvk\Web\Models\Repositories\Users())->get($owner_id); - if(!$user) + if (!$user) { $this->fail(50, "Invalid user"); + } - if(!$user->getPrivacyPermission("audios.read", $this->getUser())) + if (!$user->getPrivacyPermission("audios.read", $this->getUser())) { $this->fail(15, "Access denied: this user chose to hide his audios"); + } } - $audios = (new Audios)->getByEntityID($owner_id, $offset, $count); - foreach($audios as $audio) + $audios = (new Audios())->getByEntityID($owner_id, $offset, $count); + foreach ($audios as $audio) { $items[] = $this->toSafeAudioStruct($audio, $hash, $need_user == 1); + } return (object) [ "count" => sizeof($items), "items" => $items, ]; - } + } - function getLyrics(int $lyrics_id): object + public function getLyrics(int $lyrics_id): object { $this->requireUser(); - $audio = (new Audios)->get($lyrics_id); - if(!$audio || !$audio->getLyrics()) - $this->fail(0404, "Not found"); + $audio = (new Audios())->get($lyrics_id); + if (!$audio || !$audio->getLyrics()) { + $this->fail(0o404, "Not found"); + } - if(!$audio->canBeViewedBy($this->getUser())) + if (!$audio->canBeViewedBy($this->getUser())) { $this->fail(201, "Access denied to lyrics"); + } return (object) [ "lyrics_id" => $lyrics_id, @@ -359,39 +391,41 @@ final class Audio extends VKAPIRequestHandler ]; } - function beacon(int $aid, ?int $gid = NULL): int + public function beacon(int $aid, ?int $gid = null): int { $this->requireUser(); $this->willExecuteWriteAction(); - $audio = (new Audios)->get($aid); - if(!$audio) - $this->fail(0404, "Not Found"); - else if(!$audio->canBeViewedBy($this->getUser())) + $audio = (new Audios())->get($aid); + if (!$audio) { + $this->fail(0o404, "Not Found"); + } elseif (!$audio->canBeViewedBy($this->getUser())) { $this->fail(201, "Insufficient permissions to listen this audio"); + } - $group = NULL; - if(!is_null($gid)) { - $group = (new Clubs)->get($gid); - if(!$group) - $this->fail(0404, "Not Found"); - else if(!$group->canBeModifiedBy($this->getUser())) + $group = null; + if (!is_null($gid)) { + $group = (new Clubs())->get($gid); + if (!$group) { + $this->fail(0o404, "Not Found"); + } elseif (!$group->canBeModifiedBy($this->getUser())) { $this->fail(203, "Insufficient rights to this group"); + } } return (int) $audio->listen($group ?? $this->getUser()); } - function setBroadcast(string $audio, string $target_ids): array + public function setBroadcast(string $audio, string $target_ids): array { $this->requireUser(); [$owner, $aid] = explode("_", $audio); - $song = (new Audios)->getByOwnerAndVID((int) $owner, (int) $aid); + $song = (new Audios())->getByOwnerAndVID((int) $owner, (int) $aid); $ids = []; - foreach(explode(",", $target_ids) as $id) { + foreach (explode(",", $target_ids) as $id) { $id = (int) $id; - if($id > 0) { + if ($id > 0) { if ($id != $this->getUser()->getId()) { $this->fail(600, "Can't listen on behalf of $id"); } else { @@ -401,11 +435,12 @@ final class Audio extends VKAPIRequestHandler } } - $group = (new Clubs)->get($id * -1); - if(!$group) - $this->fail(0404, "Not Found"); - else if(!$group->canBeModifiedBy($this->getUser())) - $this->fail(203,"Insufficient rights to this group"); + $group = (new Clubs())->get($id * -1); + if (!$group) { + $this->fail(0o404, "Not Found"); + } elseif (!$group->canBeModifiedBy($this->getUser())) { + $this->fail(203, "Insufficient rights to this group"); + } $ids[] = $id; $this->beacon($song ? $song->getId() : 0, $id * -1); @@ -414,20 +449,21 @@ final class Audio extends VKAPIRequestHandler return $ids; } - function getBroadcastList(string $filter = "all", int $active = 0, ?string $hash = NULL): object + public function getBroadcastList(string $filter = "all", int $active = 0, ?string $hash = null): object { $this->requireUser(); - if(!in_array($filter, ["all", "friends", "groups"])) + if (!in_array($filter, ["all", "friends", "groups"])) { $this->fail(8, "Invalid filter $filter"); + } $broadcastList = $this->getUser()->getBroadcastList($filter); $items = []; - foreach($broadcastList as $res) { + foreach ($broadcastList as $res) { $struct = $res->toVkApiStruct(); $status = $res->getCurrentAudioStatus(); - $struct->status_audio = $status ? $this->toSafeAudioStruct($status) : NULL; + $struct->status_audio = $status ? $this->toSafeAudioStruct($status) : null; $items[] = $struct; } @@ -437,41 +473,46 @@ final class Audio extends VKAPIRequestHandler ]; } - function edit(int $owner_id, int $audio_id, ?string $artist = NULL, ?string $title = NULL, ?string $text = NULL, ?int $genre_id = NULL, ?string $genre_str = NULL, int $no_search = 0): int + public function edit(int $owner_id, int $audio_id, ?string $artist = null, ?string $title = null, ?string $text = null, ?int $genre_id = null, ?string $genre_str = null, int $no_search = 0): int { $this->requireUser(); $this->willExecuteWriteAction(); - $audio = (new Audios)->getByOwnerAndVID($owner_id, $audio_id); - if(!$audio) - $this->fail(0404, "Not Found"); - else if(!$audio->canBeModifiedBy($this->getUser())) + $audio = (new Audios())->getByOwnerAndVID($owner_id, $audio_id); + if (!$audio) { + $this->fail(0o404, "Not Found"); + } elseif (!$audio->canBeModifiedBy($this->getUser())) { $this->fail(201, "Insufficient permissions to edit this audio"); + } - if(!is_null($genre_id)) { - $genre = array_flip(AEntity::vkGenres)[$genre_id] ?? NULL; - if(!$genre) + if (!is_null($genre_id)) { + $genre = array_flip(AEntity::vkGenres)[$genre_id] ?? null; + if (!$genre) { $this->fail(8, "Invalid genre ID $genre_id"); + } $audio->setGenre($genre); - } else if(!is_null($genre_str)) { - if(!in_array($genre_str, AEntity::genres)) + } elseif (!is_null($genre_str)) { + if (!in_array($genre_str, AEntity::genres)) { $this->fail(8, "Invalid genre ID $genre_str"); + } $audio->setGenre($genre_str); } $lyrics = 0; - if(!is_null($text)) { + if (!is_null($text)) { $audio->setLyrics($text); $lyrics = $audio->getId(); } - if(!is_null($artist)) + if (!is_null($artist)) { $audio->setPerformer($artist); + } - if(!is_null($title)) + if (!is_null($title)) { $audio->setName($title); + } $audio->setSearchability(!((bool) $no_search)); $audio->setEdited(time()); @@ -480,67 +521,72 @@ final class Audio extends VKAPIRequestHandler return $lyrics; } - function add(int $audio_id, int $owner_id, ?int $group_id = NULL, ?int $album_id = NULL): string + public function add(int $audio_id, int $owner_id, ?int $group_id = null, ?int $album_id = null): string { $this->requireUser(); $this->willExecuteWriteAction(); - if(!is_null($album_id)) + if (!is_null($album_id)) { $this->fail(10, "album_id not implemented"); + } // TODO get rid of dups $to = $this->getUser(); - if(!is_null($group_id)) { - $group = (new Clubs)->get($group_id); - if(!$group) - $this->fail(0404, "Invalid group_id"); - else if(!$group->canBeModifiedBy($this->getUser())) + if (!is_null($group_id)) { + $group = (new Clubs())->get($group_id); + if (!$group) { + $this->fail(0o404, "Invalid group_id"); + } elseif (!$group->canBeModifiedBy($this->getUser())) { $this->fail(203, "Insufficient rights to this group"); + } $to = $group; } - $audio = (new Audios)->getByOwnerAndVID($owner_id, $audio_id); - if(!$audio) - $this->fail(0404, "Not found"); - else if(!$audio->canBeViewedBy($this->getUser())) + $audio = (new Audios())->getByOwnerAndVID($owner_id, $audio_id); + if (!$audio) { + $this->fail(0o404, "Not found"); + } elseif (!$audio->canBeViewedBy($this->getUser())) { $this->fail(201, "Access denied to audio(owner=$owner_id, vid=$audio_id)"); + } try { $audio->add($to); - } catch(\OverflowException $ex) { + } catch (\OverflowException $ex) { $this->fail(300, "Album is full"); } return $audio->getPrettyId(); } - function delete(int $audio_id, int $owner_id, ?int $group_id = NULL): int + public function delete(int $audio_id, int $owner_id, ?int $group_id = null): int { $this->requireUser(); $this->willExecuteWriteAction(); $from = $this->getUser(); - if(!is_null($group_id)) { - $group = (new Clubs)->get($group_id); - if(!$group) - $this->fail(0404, "Invalid group_id"); - else if(!$group->canBeModifiedBy($this->getUser())) + if (!is_null($group_id)) { + $group = (new Clubs())->get($group_id); + if (!$group) { + $this->fail(0o404, "Invalid group_id"); + } elseif (!$group->canBeModifiedBy($this->getUser())) { $this->fail(203, "Insufficient rights to this group"); + } $from = $group; } - $audio = (new Audios)->getByOwnerAndVID($owner_id, $audio_id); - if(!$audio) - $this->fail(0404, "Not found"); + $audio = (new Audios())->getByOwnerAndVID($owner_id, $audio_id); + if (!$audio) { + $this->fail(0o404, "Not found"); + } $audio->remove($from); return 1; } - function restore(int $audio_id, int $owner_id, ?int $group_id = NULL, ?string $hash = NULL): object + public function restore(int $audio_id, int $owner_id, ?int $group_id = null, ?string $hash = null): object { $this->requireUser(); @@ -549,26 +595,28 @@ final class Audio extends VKAPIRequestHandler return $this->getById($vid, $hash)->items[0]; } - function getAlbums(int $owner_id = 0, int $offset = 0, int $count = 50, int $drop_private = 1): object + public function getAlbums(int $owner_id = 0, int $offset = 0, int $count = 50, int $drop_private = 1): object { $this->requireUser(); $owner_id = $owner_id == 0 ? $this->getUser()->getId() : $owner_id; $playlists = []; - if($owner_id > 0 && $owner_id != $this->getUser()->getId()) { - $user = (new \openvk\Web\Models\Repositories\Users)->get($owner_id); + if ($owner_id > 0 && $owner_id != $this->getUser()->getId()) { + $user = (new \openvk\Web\Models\Repositories\Users())->get($owner_id); - if(!$user->getPrivacyPermission("audios.read", $this->getUser())) + if (!$user->getPrivacyPermission("audios.read", $this->getUser())) { $this->fail(50, "Access to playlists denied"); + } } - foreach((new Audios)->getPlaylistsByEntityId($owner_id, $offset, $count) as $playlist) { - if(!$playlist->canBeViewedBy($this->getUser())) { - if($drop_private == 1) + foreach ((new Audios())->getPlaylistsByEntityId($owner_id, $offset, $count) as $playlist) { + if (!$playlist->canBeViewedBy($this->getUser())) { + if ($drop_private == 1) { continue; + } - $playlists[] = NULL; + $playlists[] = null; continue; } @@ -581,21 +629,23 @@ final class Audio extends VKAPIRequestHandler ]; } - function searchAlbums(string $query = '', int $offset = 0, int $limit = 25, int $drop_private = 0, int $order = 0, int $from_me = 0): object + public function searchAlbums(string $query = '', int $offset = 0, int $limit = 25, int $drop_private = 0, int $order = 0, int $from_me = 0): object { $this->requireUser(); $playlists = []; $params = []; $order_str = (['id', 'length', 'listens'][$order] ?? 'id'); - if($from_me === 1) + if ($from_me === 1) { $params['from_me'] = $this->getUser()->getId(); + } - $search = (new Audios)->findPlaylists($query, $params, ['type' => $order_str, 'invert' => false]); - foreach($search->offsetLimit($offset, $limit) as $playlist) { - if(!$playlist->canBeViewedBy($this->getUser())) { - if($drop_private == 0) - $playlists[] = NULL; + $search = (new Audios())->findPlaylists($query, $params, ['type' => $order_str, 'invert' => false]); + foreach ($search->offsetLimit($offset, $limit) as $playlist) { + if (!$playlist->canBeViewedBy($this->getUser())) { + if ($drop_private == 0) { + $playlists[] = null; + } continue; } @@ -609,55 +659,62 @@ final class Audio extends VKAPIRequestHandler ]; } - function addAlbum(string $title, ?string $description = NULL, int $group_id = 0): int + public function addAlbum(string $title, ?string $description = null, int $group_id = 0): int { $this->requireUser(); $this->willExecuteWriteAction(); - $group = NULL; - if($group_id != 0) { - $group = (new Clubs)->get($group_id); - if(!$group) - $this->fail(0404, "Invalid group_id"); - else if(!$group->canBeModifiedBy($this->getUser())) + $group = null; + if ($group_id != 0) { + $group = (new Clubs())->get($group_id); + if (!$group) { + $this->fail(0o404, "Invalid group_id"); + } elseif (!$group->canBeModifiedBy($this->getUser())) { $this->fail(600, "Insufficient rights to this group"); + } } - $album = new Playlist; + $album = new Playlist(); $album->setName($title); - if(!is_null($group)) + if (!is_null($group)) { $album->setOwner($group_id * -1); - else + } else { $album->setOwner($this->getUser()->getId()); + } - if(!is_null($description)) + if (!is_null($description)) { $album->setDescription($description); + } $album->save(); - if(!is_null($group)) + if (!is_null($group)) { $album->bookmark($group); - else + } else { $album->bookmark($this->getUser()); + } return $album->getId(); } - function editAlbum(int $album_id, ?string $title = NULL, ?string $description = NULL): int + public function editAlbum(int $album_id, ?string $title = null, ?string $description = null): int { $this->requireUser(); $this->willExecuteWriteAction(); - $album = (new Audios)->getPlaylist($album_id); - if(!$album) - $this->fail(0404, "Album not found"); - else if(!$album->canBeModifiedBy($this->getUser())) + $album = (new Audios())->getPlaylist($album_id); + if (!$album) { + $this->fail(0o404, "Album not found"); + } elseif (!$album->canBeModifiedBy($this->getUser())) { $this->fail(600, "Insufficient rights to this album"); + } - if(!is_null($title)) + if (!is_null($title)) { $album->setName($title); + } - if(!is_null($description)) + if (!is_null($description)) { $album->setDescription($description); + } $album->setEdited(time()); $album->save(); @@ -665,128 +722,143 @@ final class Audio extends VKAPIRequestHandler return (int) !(!$title && !$description); } - function deleteAlbum(int $album_id): int + public function deleteAlbum(int $album_id): int { $this->requireUser(); $this->willExecuteWriteAction(); - $album = (new Audios)->getPlaylist($album_id); - if(!$album) - $this->fail(0404, "Album not found"); - else if(!$album->canBeModifiedBy($this->getUser())) + $album = (new Audios())->getPlaylist($album_id); + if (!$album) { + $this->fail(0o404, "Album not found"); + } elseif (!$album->canBeModifiedBy($this->getUser())) { $this->fail(600, "Insufficient rights to this album"); + } $album->delete(); return 1; } - function moveToAlbum(int $album_id, string $audio_ids): int + public function moveToAlbum(int $album_id, string $audio_ids): int { $this->requireUser(); $this->willExecuteWriteAction(); - $album = (new Audios)->getPlaylist($album_id); - if(!$album) - $this->fail(0404, "Album not found"); - else if(!$album->canBeModifiedBy($this->getUser())) + $album = (new Audios())->getPlaylist($album_id); + if (!$album) { + $this->fail(0o404, "Album not found"); + } elseif (!$album->canBeModifiedBy($this->getUser())) { $this->fail(600, "Insufficient rights to this album"); + } $audios = []; $audio_ids = array_unique(explode(",", $audio_ids)); - if(sizeof($audio_ids) < 1 || sizeof($audio_ids) > 1000) + if (sizeof($audio_ids) < 1 || sizeof($audio_ids) > 1000) { $this->fail(8, "audio_ids must contain at least 1 audio and at most 1000"); + } - foreach($audio_ids as $audio_id) { + foreach ($audio_ids as $audio_id) { $audio = $this->audioFromAnyId($audio_id); - if(!$audio) + if (!$audio) { continue; - else if(!$audio->canBeViewedBy($this->getUser())) + } elseif (!$audio->canBeViewedBy($this->getUser())) { continue; + } $audios[] = $audio; } - if(sizeof($audios) < 1) + if (sizeof($audios) < 1) { return 0; + } $res = 1; try { - foreach ($audios as $audio) + foreach ($audios as $audio) { $res = min($res, (int) $album->add($audio)); - } catch(\OutOfBoundsException $ex) { + } + } catch (\OutOfBoundsException $ex) { return 0; } return $res; } - function removeFromAlbum(int $album_id, string $audio_ids): int + public function removeFromAlbum(int $album_id, string $audio_ids): int { $this->requireUser(); $this->willExecuteWriteAction(); - $album = (new Audios)->getPlaylist($album_id); - if(!$album) - $this->fail(0404, "Album not found"); - else if(!$album->canBeModifiedBy($this->getUser())) + $album = (new Audios())->getPlaylist($album_id); + if (!$album) { + $this->fail(0o404, "Album not found"); + } elseif (!$album->canBeModifiedBy($this->getUser())) { $this->fail(600, "Insufficient rights to this album"); + } $audios = []; $audio_ids = array_unique(explode(",", $audio_ids)); - if(sizeof($audio_ids) < 1 || sizeof($audio_ids) > 1000) + if (sizeof($audio_ids) < 1 || sizeof($audio_ids) > 1000) { $this->fail(8, "audio_ids must contain at least 1 audio and at most 1000"); + } - foreach($audio_ids as $audio_id) { + foreach ($audio_ids as $audio_id) { $audio = $this->audioFromAnyId($audio_id); - if(!$audio) + if (!$audio) { continue; - else if($audio->canBeViewedBy($this->getUser())) + } elseif ($audio->canBeViewedBy($this->getUser())) { continue; + } $audios[] = $audio; } - if(sizeof($audios) < 1) + if (sizeof($audios) < 1) { return 0; + } - foreach($audios as $audio) + foreach ($audios as $audio) { $album->remove($audio); + } return 1; } - function copyToAlbum(int $album_id, string $audio_ids): int + public function copyToAlbum(int $album_id, string $audio_ids): int { return $this->moveToAlbum($album_id, $audio_ids); } - function bookmarkAlbum(int $id): int + public function bookmarkAlbum(int $id): int { $this->requireUser(); $this->willExecuteWriteAction(); - $album = (new Audios)->getPlaylist($id); - if(!$album) - $this->fail(0404, "Not found"); + $album = (new Audios())->getPlaylist($id); + if (!$album) { + $this->fail(0o404, "Not found"); + } - if(!$album->canBeViewedBy($this->getUser())) + if (!$album->canBeViewedBy($this->getUser())) { $this->fail(600, "Access error"); + } return (int) $album->bookmark($this->getUser()); } - function unBookmarkAlbum(int $id): int + public function unBookmarkAlbum(int $id): int { $this->requireUser(); $this->willExecuteWriteAction(); - $album = (new Audios)->getPlaylist($id); - if(!$album) - $this->fail(0404, "Not found"); + $album = (new Audios())->getPlaylist($id); + if (!$album) { + $this->fail(0o404, "Not found"); + } - if(!$album->canBeViewedBy($this->getUser())) + if (!$album->canBeViewedBy($this->getUser())) { $this->fail(600, "Access error"); + } return (int) $album->unbookmark($this->getUser()); } diff --git a/VKAPI/Handlers/Board.php b/VKAPI/Handlers/Board.php index b7cb7e69..f2f3ec76 100644 --- a/VKAPI/Handlers/Board.php +++ b/VKAPI/Handlers/Board.php @@ -1,5 +1,9 @@ -requireUser(); $this->willExecuteWriteAction(); - $club = (new ClubsRepo)->get($group_id); + $club = (new ClubsRepo())->get($group_id); - if(!$club) { + if (!$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"); } $flags = 0; - if($from_group == true && $club->canBeModifiedBy($this->getUser())) + if ($from_group == true && $club->canBeModifiedBy($this->getUser())) { $flags |= 0b10000000; - - $topic = new Topic; + } + + $topic = new Topic(); $topic->setGroup($club->getId()); $topic->setOwner($this->getUser()->getId()); $topic->setTitle(ovk_proc_strtr($title, 127)); @@ -39,8 +44,8 @@ final class Board extends VKAPIRequestHandler $topic->setFlags($flags); $topic->save(); - if(!empty($text)) { - $comment = new Comment; + if (!empty($text)) { + $comment = new Comment(); $comment->setOwner($this->getUser()->getId()); $comment->setModel(get_class($topic)); $comment->setTarget($topic->getId()); @@ -48,45 +53,51 @@ final class Board extends VKAPIRequestHandler $comment->setCreated(time()); $comment->setFlags($flags); $comment->save(); - - if(!empty($attachments)) { + + if (!empty($attachments)) { $attachmentsArr = explode(",", $attachments); # блин а мне это везде копировать типа - if(sizeof($attachmentsArr) > 10) + if (sizeof($attachmentsArr) > 10) { $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"; - elseif(str_contains($attac, "video")) + } elseif (str_contains($attac, "video")) { $attachmentType = "video"; - else + } else { $this->fail(205, "Unknown attachment type"); + } $attachment = str_replace($attachmentType, "", $attac); - $attachmentOwner = (int)explode("_", $attachment)[0]; - $attachmentId = (int)end(explode("_", $attachment)); + $attachmentOwner = (int) explode("_", $attachment)[0]; + $attachmentId = (int) end(explode("_", $attachment)); - $attacc = NULL; + $attacc = null; - if($attachmentType == "photo") { - $attacc = (new PhotosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId); - if(!$attacc || $attacc->isDeleted()) + if ($attachmentType == "photo") { + $attacc = (new PhotosRepo())->getByOwnerAndVID($attachmentOwner, $attachmentId); + if (!$attacc || $attacc->isDeleted()) { $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"); - + } + $comment->attach($attacc); - } elseif($attachmentType == "video") { - $attacc = (new VideosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId); - if(!$attacc || $attacc->isDeleted()) + } elseif ($attachmentType == "video") { + $attacc = (new VideosRepo())->getByOwnerAndVID($attachmentOwner, $attachmentId); + if (!$attacc || $attacc->isDeleted()) { $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"); + } $comment->attach($attacc); } @@ -100,18 +111,18 @@ final class Board extends VKAPIRequestHandler return $topic->getId(); } - function closeTopic(int $group_id, int $topic_id) + public function closeTopic(int $group_id, int $topic_id) { $this->requireUser(); $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; } - if(!$topic->isClosed()) { + if (!$topic->isClosed()) { $topic->setClosed(1); $topic->save(); } @@ -119,31 +130,32 @@ final class Board extends VKAPIRequestHandler 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->willExecuteWriteAction(); - if(empty($message) && empty($attachments)) { + if (empty($message) && empty($attachments)) { $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."); } $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; + } - if(strlen($message) > 300) { + if (strlen($message) > 300) { $this->fail(20, "Comment is too long."); } - $comment = new Comment; + $comment = new Comment(); $comment->setOwner($this->getUser()->getId()); $comment->setModel(get_class($topic)); $comment->setTarget($topic->getId()); @@ -152,43 +164,49 @@ final class Board extends VKAPIRequestHandler $comment->setFlags($flags); $comment->save(); - if(!empty($attachments)) { + if (!empty($attachments)) { $attachmentsArr = explode(",", $attachments); - if(sizeof($attachmentsArr) > 10) + if (sizeof($attachmentsArr) > 10) { $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"; - elseif(str_contains($attac, "video")) + } elseif (str_contains($attac, "video")) { $attachmentType = "video"; - else + } else { $this->fail(205, "Unknown attachment type"); + } $attachment = str_replace($attachmentType, "", $attac); - $attachmentOwner = (int)explode("_", $attachment)[0]; - $attachmentId = (int)end(explode("_", $attachment)); + $attachmentOwner = (int) explode("_", $attachment)[0]; + $attachmentId = (int) end(explode("_", $attachment)); - $attacc = NULL; + $attacc = null; - if($attachmentType == "photo") { - $attacc = (new PhotosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId); - if(!$attacc || $attacc->isDeleted()) + if ($attachmentType == "photo") { + $attacc = (new PhotosRepo())->getByOwnerAndVID($attachmentOwner, $attachmentId); + if (!$attacc || $attacc->isDeleted()) { $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"); - + } + $comment->attach($attacc); - } elseif($attachmentType == "video") { - $attacc = (new VideosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId); - if(!$attacc || $attacc->isDeleted()) + } elseif ($attachmentType == "video") { + $attacc = (new VideosRepo())->getByOwnerAndVID($attachmentOwner, $attachmentId); + if (!$attacc || $attacc->isDeleted()) { $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"); + } $comment->attach($attacc); } @@ -198,29 +216,30 @@ final class Board extends VKAPIRequestHandler 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->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"); + } $comment->delete(); return 1; } - function deleteTopic(int $group_id, int $topic_id) + public function deleteTopic(int $group_id, int $topic_id) { $this->requireUser(); $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; } @@ -229,7 +248,7 @@ final class Board extends VKAPIRequestHandler 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(); @@ -239,7 +258,7 @@ final class Board extends VKAPIRequestHandler if($comment->getOwner() != $this->getUser()->getId()) $this->fail(15, "Access to comment denied"); - + $comment->setContent($message); $comment->setEdited(time()); $comment->save(); @@ -247,14 +266,14 @@ final class Board extends VKAPIRequestHandler 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->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; } @@ -265,14 +284,14 @@ final class Board extends VKAPIRequestHandler return 1; } - function fixTopic(int $group_id, int $topic_id) + public function fixTopic(int $group_id, int $topic_id) { $this->requireUser(); $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; } @@ -283,31 +302,31 @@ final class Board extends VKAPIRequestHandler 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 $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"); } $arr = [ - "items" => [] + "items" => [], ]; $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); - - if($extended) { - if($comm->getOwner() instanceof \openvk\Web\Models\Entities\User) { + + if ($extended) { + if ($comm->getOwner() instanceof \openvk\Web\Models\Entities\User) { $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(); } } @@ -316,34 +335,36 @@ final class Board extends VKAPIRequestHandler 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 ничё не делают $this->requireUser(); $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); - $arr["count"] = (new TopicsRepo)->getClubTopicsCount($club); + $topics = array_slice(iterator_to_array((new TopicsRepo())->getClubTopics($club, 1, $count + $offset)), $offset); + $arr["count"] = (new TopicsRepo())->getClubTopicsCount($club); $arr["items"] = []; $arr["default_order"] = $order; $arr["can_add_topics"] = $club->canBeModifiedBy($this->getUser()) ? true : ($club->isEveryoneCanCreateTopics() ? true : false); $arr["profiles"] = []; - if(empty($topic_ids)) { - foreach($topics as $topic) { - if($topic->isDeleted()) continue; + if (empty($topic_ids)) { + foreach ($topics as $topic) { + if ($topic->isDeleted()) { + continue; + } $arr["items"][] = $topic->toVkApiStruct($preview, $preview_length > 1 ? $preview_length : 90); } } else { $topics = explode(',', $topic_ids); - foreach($topics as $topic) { + foreach ($topics as $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); } } @@ -352,18 +373,18 @@ final class Board extends VKAPIRequestHandler return $arr; } - function openTopic(int $group_id, int $topic_id) + public function openTopic(int $group_id, int $topic_id) { $this->requireUser(); $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; } - if($topic->isClosed()) { + if ($topic->isClosed()) { $topic->setClosed(0); $topic->save(); } @@ -371,23 +392,23 @@ final class Board extends VKAPIRequestHandler 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"); } - function unfixTopic(int $group_id, int $topic_id) + public function unfixTopic(int $group_id, int $topic_id) { $this->requireUser(); $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; } - if($topic->isPinned()) { + if ($topic->isPinned()) { $topic->setClosed(0); $topic->save(); } @@ -409,21 +430,22 @@ final class Board extends VKAPIRequestHandler $res->text = $comment->getText(false); $res->attachments = []; $res->likes = []; - if($need_likes) { + if ($need_likes) { $res->likes = [ "count" => $comment->getLikesCount(), "user_likes" => (int) $comment->hasLikeFrom($this->getUser()), - "can_like" => 1 # а чё типо не может ахахаххахах + "can_like" => 1, # а чё типо не может ахахаххахах ]; } - foreach($comment->getChildren() as $attachment) { - if($attachment->isDeleted()) + foreach ($comment->getChildren() as $attachment) { + if ($attachment->isDeleted()) { continue; + } $res->attachments[] = $attachment->toVkApiStruct(); } return $res; } -} \ No newline at end of file +} diff --git a/VKAPI/Handlers/Docs.php b/VKAPI/Handlers/Docs.php index 9981243d..db1e75bb 100644 --- a/VKAPI/Handlers/Docs.php +++ b/VKAPI/Handlers/Docs.php @@ -1,48 +1,57 @@ -requireUser(); $this->willExecuteWriteAction(); - $doc = (new Documents)->getDocumentById($owner_id, $doc_id, $access_key); - if(!$doc || $doc->isDeleted()) + $doc = (new Documents())->getDocumentById($owner_id, $doc_id, $access_key); + if (!$doc || $doc->isDeleted()) { $this->fail(1150, "Invalid document id"); + } - if(!$doc->checkAccessKey($access_key)) + if (!$doc->checkAccessKey($access_key)) { $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"); + } $new_doc = $doc->copy($this->getUser()); 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->willExecuteWriteAction(); - $doc = (new Documents)->getDocumentByIdUnsafe($owner_id, $doc_id); - if(!$doc || $doc->isDeleted()) + $doc = (new Documents())->getDocumentByIdUnsafe($owner_id, $doc_id); + if (!$doc || $doc->isDeleted()) { $this->fail(1150, "Invalid document id"); + } - if(!$doc->canBeModifiedBy($this->getUser())) + if (!$doc->canBeModifiedBy($this->getUser())) { $this->fail(1153, "Access to document is denied"); + } $doc->delete(); - + return 1; } - function restore(int $owner_id, int $doc_id): int + public function restore(int $owner_id, int $doc_id): int { $this->requireUser(); $this->willExecuteWriteAction(); @@ -50,77 +59,87 @@ final class Docs extends VKAPIRequestHandler 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->willExecuteWriteAction(); - $doc = (new Documents)->getDocumentByIdUnsafe($owner_id, $doc_id); - if(!$doc || $doc->isDeleted()) + $doc = (new Documents())->getDocumentByIdUnsafe($owner_id, $doc_id); + if (!$doc || $doc->isDeleted()) { $this->fail(1150, "Invalid document id"); - if(!$doc->canBeModifiedBy($this->getUser())) + } + if (!$doc->canBeModifiedBy($this->getUser())) { $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"); - if(iconv_strlen($tags ?? "") > 256) + } + if (iconv_strlen($tags ?? "") > 256) { $this->fail(1154, "Invalid tags"); + } - if($title) + if ($title) { $doc->setName($title); + } $doc->setTags($tags); - if(in_array($folder_id, [0, 3])) + if (in_array($folder_id, [0, 3])) { $doc->setFolder_id($folder_id); - if(in_array($owner_hidden, [0, 1])) + } + if (in_array($owner_hidden, [0, 1])) { $doc->setOwner_hidden($owner_hidden); + } try { $doc->setEdited(time()); $doc->save(); - } catch(\Throwable $e) { + } catch (\Throwable $e) { return 0; } 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(); - if(!$owner_id) + if (!$owner_id) { $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); - $res = (object)[ + if ($owner_id > 0 && $owner_id != $this->getUser()->getId()) { + $this->fail(15, "Access denied"); + } + + $documents = (new Documents())->getDocumentsByOwner($owner_id, $order, $type); + $res = (object) [ "count" => $documents->size(), "items" => [], ]; - foreach($documents->offsetLimit($offset, $count) as $doc) { + foreach ($documents->offsetLimit($offset, $count) as $doc) { $res->items[] = $doc->toVkApiStruct($this->getUser(), $return_tags == 1); } return $res; } - function getById(string $docs, int $return_tags = 0): array + public function getById(string $docs, int $return_tags = 0): array { $this->requireUser(); $item_ids = explode(",", $docs); $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"); } - foreach($item_ids as $id) { + foreach ($item_ids as $id) { $splitted_id = explode("_", $id); - $doc = (new Documents)->getDocumentById((int)$splitted_id[0], (int)$splitted_id[1], $splitted_id[2]); - if(!$doc || $doc->isDeleted()) + $doc = (new Documents())->getDocumentById((int) $splitted_id[0], (int) $splitted_id[1], $splitted_id[2]); + if (!$doc || $doc->isDeleted()) { continue; + } $response[] = $doc->toVkApiStruct($this->getUser(), $return_tags === 1); } @@ -128,76 +147,76 @@ final class Docs extends VKAPIRequestHandler return $response; } - function getTypes(?int $owner_id) + public function getTypes(?int $owner_id) { $this->requireUser(); - if(!$owner_id) + if (!$owner_id) { $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"); - - $types = (new Documents)->getTypes($owner_id); + } + + $types = (new Documents())->getTypes($owner_id); return [ "count" => sizeof($types), "items" => $types, ]; } - function getTags(?int $owner_id, ?int $type = 0) + public function getTags(?int $owner_id, ?int $type = 0) { $this->requireUser(); - if(!$owner_id) + if (!$owner_id) { $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"); - - $tags = (new Documents)->getTags($owner_id, $type); + } + + $tags = (new Documents())->getTags($owner_id, $type); 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(); $params = []; $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"); + } - 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; + } - if(iconv_strlen($tags ?? "") < 512) + if (iconv_strlen($tags ?? "") < 512) { $params["tags"] = $tags; + } - if($search_own === 1) + if ($search_own === 1) { $params["from_me"] = $this->getUser()->getId(); + } - $documents = (new Documents)->find($q, $params, $o_order); - $res = (object)[ + $documents = (new Documents())->find($q, $params, $o_order); + $res = (object) [ "count" => $documents->size(), "items" => [], ]; - foreach($documents->offsetLimit($offset, $count) as $doc) { + foreach ($documents->offsetLimit($offset, $count) as $doc) { $res->items[] = $doc->toVkApiStruct($this->getUser(), $return_tags == 1); } return $res; } - function getUploadServer(?int $group_id = NULL) - { - $this->requireUser(); - $this->willExecuteWriteAction(); - - return 0; - } - - function getWallUploadServer(?int $group_id = NULL) + public function getUploadServer(?int $group_id = null) { $this->requireUser(); $this->willExecuteWriteAction(); @@ -205,7 +224,15 @@ final class Docs extends VKAPIRequestHandler 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->willExecuteWriteAction(); diff --git a/VKAPI/Handlers/Friends.php b/VKAPI/Handlers/Friends.php index 51046be4..77de7d9d 100644 --- a/VKAPI/Handlers/Friends.php +++ b/VKAPI/Handlers/Friends.php @@ -1,188 +1,195 @@ -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); - - 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."); - - foreach($user->getFriends($offset, $count) as $friend) { + } + + foreach ($user->getFriends($offset, $count) as $friend) { $friends[$i] = $friend->getId(); $i++; } - $response = $friends; + $response = $friends; - $usersApi = new Users($this->getUser()); + $usersApi = new Users($this->getUser()); - if(!is_null($fields)) - $response = $usersApi->get(implode(',', $friends), $fields, 0, $count); # FIXME + if (!is_null($fields)) { + $response = $usersApi->get(implode(',', $friends), $fields, 0, $count); + } # FIXME - return (object) [ - "count" => $users->get($user_id)->getFriendsCount(), - "items" => $response - ]; - } + return (object) [ + "count" => $users->get($user_id)->getFriendsCount(), + "items" => $response, + ]; + } - function getLists(): object - { - $this->requireUser(); + public function getLists(): object + { + $this->requireUser(); - return (object) [ - "count" => 0, - "items" => (array)[] - ]; - } + return (object) [ + "count" => 0, + "items" => (array) [], + ]; + } - function deleteList(): int - { - $this->requireUser(); + public function deleteList(): int + { + $this->requireUser(); - return 1; - } + return 1; + } - function edit(): int - { - $this->requireUser(); + public function edit(): int + { + $this->requireUser(); - return 1; - } + return 1; + } - function editList(): int - { - $this->requireUser(); + public function editList(): int + { + $this->requireUser(); - return 1; - } + return 1; + } - function add(string $user_id): int - { - $this->requireUser(); + public function add(string $user_id): int + { + $this->requireUser(); $this->willExecuteWriteAction(); - $users = new UsersRepo; - $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"); - } + $users = new UsersRepo(); + $user = $users->get(intval($user_id)); - switch($user->getSubscriptionStatus($this->getUser())) { - case 0: - $user->toggleSubscription($this->getUser()); - return 1; + if (is_null($user)) { + $this->fail(177, "Cannot add this user to friends as user not found"); + } elseif ($user->getId() == $this->getUser()->getId()) { + $this->fail(174, "Cannot add user himself as friend"); + } - case 1: - $user->toggleSubscription($this->getUser()); - return 2; + switch ($user->getSubscriptionStatus($this->getUser())) { + case 0: + $user->toggleSubscription($this->getUser()); + return 1; - case 3: - return 2; - - default: - return 1; - } - } + case 1: + $user->toggleSubscription($this->getUser()); + return 2; - function delete(string $user_id): int - { - $this->requireUser(); + case 3: + return 2; + + default: + return 1; + } + } + + public function delete(string $user_id): int + { + $this->requireUser(); $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())) { - case 3: - $user->toggleSubscription($this->getUser()); - return 1; - - default: - $this->fail(15, "Access denied: No friend or friend request found."); - } - } + switch ($user->getSubscriptionStatus($this->getUser())) { + case 3: + $user->toggleSubscription($this->getUser()); + return 1; - function areFriends(string $user_ids): array - { - $this->requireUser(); + default: + $this->fail(15, "Access denied: No friend or friend request found."); + } + } - $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++) { - $friend = $users->get(intval($friends[$i])); + $response = []; - $response[] = (object)[ - "friend_status" => $friend->getSubscriptionStatus($this->getUser()), - "user_id" => $friend->getId() - ]; - } + for ($i = 0; $i < sizeof($friends); $i++) { + $friend = $users->get(intval($friends[$i])); - 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 - { - if ($count >= 1000) - $this->fail(100, "One of the required parameters was not passed or is invalid."); + return $response; + } - $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; - $offset++; - $followers = []; + $this->requireUser(); - if ($out != 0) { - 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++; - } - } + $i = 0; + $offset++; + $followers = []; - $response = $followers; - $usersApi = new Users($this->getUser()); + if ($out != 0) { + 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) - $user->user_id = $user->id; + $response = $usersApi->get(implode(',', $followers), $fields, 0, $count); - return (object) [ - "count" => $this->getUser()->getFollowersCount(), - "items" => $response - ]; - } + foreach ($response as $user) { + $user->user_id = $user->id; + } + + return (object) [ + "count" => $this->getUser()->getFollowersCount(), + "items" => $response, + ]; + } } diff --git a/VKAPI/Handlers/Gifts.php b/VKAPI/Handlers/Gifts.php index 0d1fc598..fe1232b7 100644 --- a/VKAPI/Handlers/Gifts.php +++ b/VKAPI/Handlers/Gifts.php @@ -1,12 +1,16 @@ -requireUser(); @@ -14,94 +18,104 @@ final class Gifts extends VKAPIRequestHandler $i += $offset; $server_url = ovk_scheme(true) . $_SERVER["HTTP_HOST"]; - if($user_id) - $user = (new UsersRepo)->get($user_id); - else + if ($user_id) { + $user = (new UsersRepo())->get($user_id); + } else { $user = $this->getUser(); + } - if(!$user || $user->isDeleted()) + if (!$user || $user->isDeleted()) { $this->fail(177, "Invalid user"); + } - if(!$user->canBeViewedBy($this->getUser())) + if (!$user->canBeViewedBy($this->getUser())) { $this->fail(15, "Access denied"); + } /* if(!$user->getPrivacyPermission('gifts.read', $this->getUser())) $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"); + } $gift_item = []; $userGifts = array_slice(iterator_to_array($user->getGifts(1, $count, false)), $offset); - if(sizeof($userGifts) < 0) { - return NULL; + if (sizeof($userGifts) < 0) { + return null; } - foreach($userGifts as $gift) { - if($i < $count) { + foreach ($userGifts as $gift) { + if ($i < $count) { $gift_item[] = [ "id" => $i, "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(), "gift" => [ "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_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; } - 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->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"); - - if(!$user || $user->isDeleted()) + } + + if (!$user || $user->isDeleted()) { $this->fail(177, "Invalid user"); + } - if(!$user->canBeViewedBy($this->getUser())) + if (!$user->canBeViewedBy($this->getUser())) { $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"); - + } + $price = $gift->getPrice(); $coinsLeft = $this->getUser()->getCoins() - $price; - if(!$gift->canUse($this->getUser())) + if (!$gift->canUse($this->getUser())) { return (object) [ "success" => 0, "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) [ "success" => 0, "user_ids" => $user_ids, - "error" => "You don't have enough voices." + "error" => "You don't have enough voices.", ]; + } $user->gift($this->getUser(), $gift, $message); $gift->used(); @@ -116,11 +130,11 @@ final class Gifts extends VKAPIRequestHandler [ "success" => 1, "user_ids" => $user_ids, - "withdraw_votes" => $price + "withdraw_votes" => $price, ]; } - function delete() + public function delete() { $this->requireUser(); $this->willExecuteWriteAction(); @@ -129,27 +143,28 @@ final class Gifts extends VKAPIRequestHandler } # в 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 = []; $i = 0; $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"); + } - foreach($cats as $cat) { + foreach ($cats as $cat) { $categ[$i] = [ "name" => $cat->getName(), "description" => $cat->getDescription(), "id" => $cat->getId(), "thumbnail" => $server_url . $cat->getThumbnailURL(), ]; - - if($extended == true) { + + if ($extended == true) { $categ[$i]["localizations"] = []; - foreach(getLanguages() as $lang) { + foreach (getLanguages() as $lang) { $code = $lang["code"]; $categ[$i]["localizations"][$code] = [ @@ -160,30 +175,32 @@ final class Gifts extends VKAPIRequestHandler } $i++; } - + return $categ; } - function getGiftsInCategory(int $id, int $page = 1) + public function getGiftsInCategory(int $id, int $page = 1) { $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"); + } - if(!(new GiftsRepo)->getCat($id)) + if (!(new GiftsRepo())->getCat($id)) { $this->fail(177, "Category not found"); + } - $giftz = ((new GiftsRepo)->getCat($id))->getGifts($page); + $giftz = ((new GiftsRepo())->getCat($id))->getGifts($page); $gifts = []; - foreach($giftz as $gift) { + foreach ($giftz as $gift) { $gifts[] = [ "name" => $gift->getName(), "image" => $gift->getImage(2), - "usages_left" => (int)$gift->getUsagesLeft($this->getUser()), + "usages_left" => (int) $gift->getUsagesLeft($this->getUser()), "price" => $gift->getPrice(), - "is_free" => $gift->isFree() + "is_free" => $gift->isFree(), ]; } diff --git a/VKAPI/Handlers/Groups.php b/VKAPI/Handlers/Groups.php index bd546c3d..baf78210 100644 --- a/VKAPI/Handlers/Groups.php +++ b/VKAPI/Handlers/Groups.php @@ -1,5 +1,9 @@ -requireUser(); # 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'); } $clbs = []; - if($user_id == 0) { - foreach($this->getUser()->getClubs($offset, $filter == "admin", $count, true) as $club) - $clbs[] = $club; - $clbsCount = $this->getUser()->getClubCount(); + if ($user_id == 0) { + foreach ($this->getUser()->getClubs($offset, $filter == "admin", $count, true) as $club) { + $clbs[] = $club; + } + $clbsCount = $this->getUser()->getClubCount(); } else { - $users = new UsersRepo; - $user = $users->get($user_id); + $users = new UsersRepo(); + $user = $users->get($user_id); - if(is_null($user) || $user->isDeleted()) - $this->fail(15, "Access denied"); + if (is_null($user) || $user->isDeleted()) { + $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."); - - 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; $ic = sizeof($clbs); - if(sizeof($clbs) > $count) + if (sizeof($clbs) > $count) { $ic = $count; + } - if(!empty($clbs)) { - for($i=0; $i < $ic; $i++) { + if (!empty($clbs)) { + for ($i = 0; $i < $ic; $i++) { $usr = $clbs[$i]; - if(is_null($usr)) { + if (is_null($usr)) { } else { $rClubs[$i] = (object) [ @@ -59,8 +68,8 @@ final class Groups extends VKAPIRequestHandler $flds = explode(',', $fields); - foreach($flds as $field) { - switch($field) { + foreach ($flds as $field) { + switch ($field) { case "verified": $rClubs[$i]->verified = intval($usr->isVerified()); break; @@ -98,15 +107,15 @@ final class Groups extends VKAPIRequestHandler $backgrounds = $usr->getBackDropPictureURLs(); $rClubs[$i]->background = $backgrounds; break; - # unstandard feild + # unstandard feild case "suggested_count": - if($usr->getWallType() != 2) { - $rClubs[$i]->suggested_count = NULL; + if ($usr->getWallType() != 2) { + $rClubs[$i]->suggested_count = null; break; } - + $rClubs[$i]->suggested_count = $usr->getSuggestedPostsCount($this->getUser()); - + break; } } @@ -117,58 +126,63 @@ final class Groups extends VKAPIRequestHandler } return (object) [ - "count" => $clbsCount, - "items" => $rClubs + "count" => $clbsCount, + "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 */ - $clubs = new ClubsRepo; - - if(empty($group_ids) && !empty($group_id)) + $clubs = new ClubsRepo(); + + if (empty($group_ids) && !empty($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"); - + } + $clbs = explode(',', $group_ids); - $response = array(); + $response = []; $ic = sizeof($clbs); - if(sizeof($clbs) > $count) - $ic = $count; + if (sizeof($clbs) > $count) { + $ic = $count; + } $clbs = array_slice($clbs, $offset * $count); - for($i=0; $i < $ic; $i++) { - if($i > 500 || $clbs[$i] == 0) + for ($i = 0; $i < $ic; $i++) { + if ($i > 500 || $clbs[$i] == 0) { break; + } - if($clbs[$i] < 0) + if ($clbs[$i] < 0) { $this->fail(100, "ты ошибся чутка, у айди группы убери минус"); + } $clb = $clubs->get((int) $clbs[$i]); - if(is_null($clb)) { - $response[$i] = (object)[ + if (is_null($clb)) { + $response[$i] = (object) [ "id" => intval($clbs[$i]), "name" => "DELETED", - "screen_name" => "club".intval($clbs[$i]), + "screen_name" => "club" . intval($clbs[$i]), "type" => "group", - "description" => "This group was deleted or it doesn't exist" - ]; - } else if($clbs[$i] == NULL) { + "description" => "This group was deleted or it doesn't exist", + ]; + } elseif ($clbs[$i] == null) { } else { - $response[$i] = (object)[ + $response[$i] = (object) [ "id" => $clb->getId(), "name" => $clb->getName(), - "screen_name" => $clb->getShortCode() ?? "club".$clb->getId(), + "screen_name" => $clb->getShortCode() ?? "club" . $clb->getId(), "is_closed" => false, "type" => "group", "is_member" => !is_null($this->getUser()) ? (int) $clb->getSubscriptionStatus($this->getUser()) : 0, @@ -177,20 +191,20 @@ final class Groups extends VKAPIRequestHandler $flds = explode(',', $fields); - foreach($flds as $field) { - switch($field) { - case "verified": - $response[$i]->verified = intval($clb->isVerified()); - break; - case "has_photo": - $response[$i]->has_photo = is_null($clb->getAvatarPhoto()) ? 0 : 1; - break; - case "photo_max_orig": - $response[$i]->photo_max_orig = $clb->getAvatarURL(); - break; - case "photo_max": - $response[$i]->photo_max = $clb->getAvatarURL(); - break; + foreach ($flds as $field) { + switch ($field) { + case "verified": + $response[$i]->verified = intval($clb->isVerified()); + break; + case "has_photo": + $response[$i]->has_photo = is_null($clb->getAvatarPhoto()) ? 0 : 1; + break; + case "photo_max_orig": + $response[$i]->photo_max_orig = $clb->getAvatarURL(); + break; + case "photo_max": + $response[$i]->photo_max = $clb->getAvatarURL(); + break; case "photo_50": $response[$i]->photo_50 = $clb->getAvatarURL(); break; @@ -206,14 +220,14 @@ final class Groups extends VKAPIRequestHandler case "photo_400_orig": $response[$i]->photo_400_orig = $clb->getAvatarURL("normal"); break; - case "members_count": - $response[$i]->members_count = $clb->getFollowersCount(); - break; - case "site": - $response[$i]->site = $clb->getWebsite(); - break; + case "members_count": + $response[$i]->members_count = $clb->getFollowersCount(); + break; + case "site": + $response[$i]->site = $clb->getWebsite(); + break; case "description": - $response[$i]->description = $clb->getDescription(); + $response[$i]->description = $clb->getDescription(); break; case "can_suggest": $response[$i]->can_suggest = !$clb->canBeModifiedBy($this->getUser()) && $clb->getWallType() == 2; @@ -222,10 +236,10 @@ final class Groups extends VKAPIRequestHandler $backgrounds = $clb->getBackDropPictureURLs(); $response[$i]->background = $backgrounds; break; - # unstandard feild + # unstandard feild case "suggested_count": - if($clb->getWallType() != 2) { - $response[$i]->suggested_count = NULL; + if ($clb->getWallType() != 2) { + $response[$i]->suggested_count = null; break; } @@ -235,20 +249,23 @@ final class Groups extends VKAPIRequestHandler $contacts; $contactTmp = $clb->getManagers(1, true); - foreach($contactTmp as $contact) - $contacts[] = array( + foreach ($contactTmp as $contact) { + $contacts[] = [ "user_id" => $contact->getUser()->getId(), - "desc" => $contact->getComment() - ); + "desc" => $contact->getComment(), + ]; + } - $response[$i]->contacts = $contacts; - break; + $response[$i]->contacts = $contacts; + break; case "can_post": - if(!is_null($this->getUser())) - if($clb->canBeModifiedBy($this->getUser())) + if (!is_null($this->getUser())) { + if ($clb->canBeModifiedBy($this->getUser())) { $response[$i]->can_post = true; - else + } else { $response[$i]->can_post = $clb->canPost(); + } + } break; } } @@ -258,21 +275,22 @@ final class Groups extends VKAPIRequestHandler 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"); } - $clubs = new ClubsRepo; - - $array = []; - $find = $clubs->find($q); + $clubs = new ClubsRepo(); - foreach ($find->offsetLimit($offset, $count) as $group) + $array = []; + $find = $clubs->find($q); + + foreach ($find->offsetLimit($offset, $count) as $group) { $array[] = $group->getId(); - - if(!$array || sizeof($array) < 1) { + } + + if (!$array || sizeof($array) < 1) { return (object) [ "count" => 0, "items" => [], @@ -280,47 +298,49 @@ final class Groups extends VKAPIRequestHandler } return (object) [ - "count" => $find->size(), - "items" => $this->getById(implode(',', $array), "", $fields) + "count" => $find->size(), + "items" => $this->getById(implode(',', $array), "", $fields), ]; } - function join(int $group_id) + public function join(int $group_id) { $this->requireUser(); $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; - if($isMember == 0) + if ($isMember == 0) { $club->toggleSubscription($this->getUser()); + } return 1; } - function leave(int $group_id) + public function leave(int $group_id) { $this->requireUser(); $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; - if($isMember == 1) + if ($isMember == 1) { $club->toggleSubscription($this->getUser()); + } 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->willExecuteWriteAction(); - $club = new Club; + $club = new Club(); $club->setName($title); $club->setAbout($description); @@ -329,73 +349,80 @@ final class Groups extends VKAPIRequestHandler $club->toggleSubscription($this->getUser()); - return $this->getById((string)$club->getId()); + return $this->getById((string) $club->getId()); } - function edit( - int $group_id, - string $title = NULL, - string $description = NULL, - string $screen_name = NULL, - string $website = NULL, - int $wall = -1, - int $topics = NULL, - int $adminlist = NULL, - int $topicsAboveWall = NULL, - int $hideFromGlobalFeed = NULL, - int $audio = NULL) - { + public function edit( + int $group_id, + string $title = null, + string $description = null, + string $screen_name = null, + string $website = null, + int $wall = -1, + int $topics = null, + int $adminlist = null, + int $topicsAboveWall = null, + int $hideFromGlobalFeed = null, + int $audio = null + ) { $this->requireUser(); $this->willExecuteWriteAction(); - $club = (new ClubsRepo)->get($group_id); + $club = (new ClubsRepo())->get($group_id); - if(!$club) $this->fail(203, "Club not found"); - 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."); + if (!$club) { + $this->fail(203, "Club not found"); + } + 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 { - $wall != -1 ? $club->setWall($wall) : NULL; - } catch(\Exception $e) { + $wall != -1 ? $club->setWall($wall) : null; + } catch (\Exception $e) { $this->fail(50, "Invalid wall value"); } - - !empty($topics) ? $club->setEveryone_Can_Create_Topics($topics) : NULL; - !empty($adminlist) ? $club->setAdministrators_List_Display($adminlist) : NULL; - !empty($topicsAboveWall) ? $club->setDisplay_Topics_Above_Wall($topicsAboveWall) : NULL; + + !empty($topics) ? $club->setEveryone_Can_Create_Topics($topics) : null; + !empty($adminlist) ? $club->setAdministrators_List_Display($adminlist) : null; + !empty($topicsAboveWall) ? $club->setDisplay_Topics_Above_Wall($topicsAboveWall) : null; 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 { $club->save(); - } catch(\TypeError $e) { + } catch (\TypeError $e) { $this->fail(15, "Nothing changed"); - } catch(\Exception $e) { + } catch (\Exception $e) { $this->fail(18, "An unknown error occurred: maybe you set an incorrect value?"); } 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 - $club = (new ClubsRepo)->get((int) $group_id); - if(!$club) + $club = (new ClubsRepo())->get((int) $group_id); + if (!$club) { $this->fail(125, "Invalid group id"); + } $sorter = "follower ASC"; - switch($sort) { + switch ($sort) { default: case "time_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); $arr = (object) [ - "count" => count($members), - "items" => array()]; - + "count" => count($members), + "items" => []]; + $filds = explode(",", $fields); $i = 0; - foreach($members as $member) { - if($i > $count) { + foreach ($members as $member) { + if ($i > $count) { break; } @@ -426,16 +453,16 @@ final class Groups extends VKAPIRequestHandler "last_name" => $member->getLastName(), ]; - foreach($filds as $fild) { + foreach ($filds as $fild) { $canView = $member->canBeViewedBy($this->getUser()); - switch($fild) { + switch ($fild) { case "bdate": - if(!$canView) { + if (!$canView) { $arr->items[$i]->bdate = "01.01.1970"; 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; case "can_post": $arr->items[$i]->can_post = $club->canBeModifiedBy($member); @@ -456,7 +483,7 @@ final class Groups extends VKAPIRequestHandler $arr->items[$i]->connections = 1; break; case "contacts": - if(!$canView) { + if (!$canView) { $arr->items[$i]->contacts = "secret@gmail.com"; break; } @@ -476,7 +503,7 @@ final class Groups extends VKAPIRequestHandler $arr->items[$i]->has_mobile = false; break; case "last_seen": - if(!$canView) { + if (!$canView) { $arr->items[$i]->last_seen = 0; break; } @@ -487,7 +514,7 @@ final class Groups extends VKAPIRequestHandler $arr->items[$i]->lists = ""; break; case "online": - if(!$canView) { + if (!$canView) { $arr->items[$i]->online = false; break; } @@ -495,7 +522,7 @@ final class Groups extends VKAPIRequestHandler $arr->items[$i]->online = $member->isOnline(); break; case "online_mobile": - if(!$canView) { + if (!$canView) { $arr->items[$i]->online_mobile = false; break; } @@ -530,7 +557,7 @@ final class Groups extends VKAPIRequestHandler $arr->items[$i]->schools = 0; break; case "sex": - if(!$canView) { + if (!$canView) { $arr->items[$i]->sex = -1; break; } @@ -538,15 +565,15 @@ final class Groups extends VKAPIRequestHandler $arr->items[$i]->sex = $member->isFemale() ? 1 : 2; break; case "site": - if(!$canView) { - $arr->items[$i]->site = NULL; + if (!$canView) { + $arr->items[$i]->site = null; break; } $arr->items[$i]->site = $member->getWebsite(); break; case "status": - if(!$canView) { + if (!$canView) { $arr->items[$i]->status = "r"; break; } @@ -563,17 +590,18 @@ final class Groups extends VKAPIRequestHandler return $arr; } - function getSettings(string $group_id) + public function getSettings(string $group_id) { $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."); + } $arr = (object) [ "title" => $club->getName(), - "description" => $club->getDescription() != NULL ? $club->getDescription() : "", + "description" => $club->getDescription() != null ? $club->getDescription() : "", "address" => $club->getShortcode(), "wall" => $club->getWallType(), # отличается от вкшных но да ладно "photos" => 1, @@ -589,13 +617,13 @@ final class Groups extends VKAPIRequestHandler "access" => 1, "subject" => 1, "subject_list" => [ - 0 => "в", - 1 => "опенвк", - 2 => "нет", - 3 => "категорий", - 4 => "групп", + 0 => "в", + 1 => "опенвк", + 2 => "нет", + 3 => "категорий", + 4 => "групп", ], - "rss" => "/club".$club->getId()."/rss", + "rss" => "/club" . $club->getId() . "/rss", "website" => $club->getWebsite(), "age_limits" => 0, "market" => [], @@ -604,24 +632,27 @@ final class Groups extends VKAPIRequestHandler 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(); - $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"); + } - $club = (new ClubsRepo)->get((int)$group_id); - $usver = (new UsersRepo)->get((int)$id); + $club = (new ClubsRepo())->get((int) $group_id); + $usver = (new UsersRepo())->get((int) $id); - if(!$club || $group_id == 0) + if (!$club || $group_id == 0) { $this->fail(203, "Invalid club"); + } - if(!$usver || $usver->isDeleted() || $user_id == 0) + if (!$usver || $usver->isDeleted() || $user_id == 0) { $this->fail(30, "Invalid user"); + } - if($extended == false) { + if ($extended == false) { return $club->getSubscriptionStatus($usver) ? 1 : 0; } else { return (object) @@ -630,12 +661,12 @@ final class Groups extends VKAPIRequestHandler "request" => 0, "invitation" => 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(); diff --git a/VKAPI/Handlers/Likes.php b/VKAPI/Handlers/Likes.php index f9262fa1..28a66911 100644 --- a/VKAPI/Handlers/Likes.php +++ b/VKAPI/Handlers/Likes.php @@ -1,206 +1,217 @@ -requireUser(); - $this->willExecuteWriteAction(); - - $postable = NULL; - switch($type) { - case "post": - $post = (new PostsRepo)->getPostById($owner_id, $item_id); - $postable = $post; - break; - case "comment": - $comment = (new CommentsRepo)->get($item_id); - $postable = $comment; - break; - case "video": - $video = (new VideosRepo)->getByOwnerAndVID($owner_id, $item_id); - $postable = $video; - break; - case "photo": - $photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $item_id); - $postable = $photo; - break; - case "note": - $note = (new NotesRepo)->getNoteById($owner_id, $item_id); - $postable = $note; - break; - default: - $this->fail(100, "One of the parameters specified was missing or invalid: incorrect type"); - } - - if(is_null($postable) || $postable->isDeleted()) - $this->fail(100, "One of the parameters specified was missing or invalid: object not found"); - - if(!$postable->canBeViewedBy($this->getUser() ?? NULL)) { - $this->fail(2, "Access to postable denied"); - } - - $postable->setLike(true, $this->getUser()); - - return (object) [ - "likes" => $postable->getLikesCount() - ]; - } - - function delete(string $type, int $owner_id, int $item_id): object - { - $this->requireUser(); - $this->willExecuteWriteAction(); - - $postable = NULL; - switch($type) { - case "post": - $post = (new PostsRepo)->getPostById($owner_id, $item_id); - $postable = $post; - break; - case "comment": - $comment = (new CommentsRepo)->get($item_id); - $postable = $comment; - break; - case "video": - $video = (new VideosRepo)->getByOwnerAndVID($owner_id, $item_id); - $postable = $video; - break; - case "photo": - $photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $item_id); - $postable = $photo; - break; - case "note": - $note = (new NotesRepo)->getNoteById($owner_id, $item_id); - $postable = $note; - break; - default: - $this->fail(100, "One of the parameters specified was missing or invalid: incorrect type"); - } - - if(is_null($postable) || $postable->isDeleted()) - $this->fail(100, "One of the parameters specified was missing or invalid: object not found"); - - if(!$postable->canBeViewedBy($this->getUser() ?? NULL)) { - $this->fail(2, "Access to postable denied"); - } - - if(!is_null($postable)) { - $postable->setLike(false, $this->getUser()); - - return (object) [ - "likes" => $postable->getLikesCount() - ]; - } - } - - function isLiked(int $user_id, string $type, int $owner_id, int $item_id): object - { - $this->requireUser(); - - $user = (new UsersRepo)->get($user_id); - - if(is_null($user) || $user->isDeleted()) - $this->fail(100, "One of the parameters specified was missing or invalid: user not found"); - - if(!$user->canBeViewedBy($this->getUser())) { - $this->fail(1984, "Access denied: you can't see this user"); - } - - $postable = NULL; - switch($type) { - case "post": - $post = (new PostsRepo)->getPostById($owner_id, $item_id); - $postable = $post; - break; - case "comment": - $comment = (new CommentsRepo)->get($item_id); - $postable = $comment; - break; - case "video": - $video = (new VideosRepo)->getByOwnerAndVID($owner_id, $item_id); - $postable = $video; - break; - case "photo": - $photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $item_id); - $postable = $photo; - break; - case "note": - $note = (new NotesRepo)->getNoteById($owner_id, $item_id); - $postable = $note; - break; - default: - $this->fail(100, "One of the parameters specified was missing or invalid: incorrect type"); - } - - if(is_null($postable) || $postable->isDeleted()) - $this->fail(100, "One of the parameters specified was missing or invalid: object not found"); - - if(!$postable->canBeViewedBy($this->getUser())) { - $this->fail(665, "Access to postable denied"); - } - - return (object) [ - "liked" => (int) $postable->hasLikeFrom($user), - "copied" => 0 - ]; - } - - function getList(string $type, int $owner_id, int $item_id, bool $extended = false, int $offset = 0, int $count = 10, bool $skip_own = false) - { - $this->requireUser(); - - $object = NULL; - - switch($type) { - case "post": - $object = (new PostsRepo)->getPostById($owner_id, $item_id); - break; - case "comment": - $object = (new CommentsRepo)->get($item_id); - break; - case "photo": - $object = (new PhotosRepo)->getByOwnerAndVID($owner_id, $item_id); - break; - case "video": - $object = (new VideosRepo)->getByOwnerAndVID($owner_id, $item_id); - break; - default: - $this->fail(58, "Invalid type"); - break; - } - - if(!$object || $object->isDeleted()) - $this->fail(56, "Invalid postable"); - - if(!$object->canBeViewedBy($this->getUser())) - $this->fail(665, "Access to postable denied"); - - $res = (object)[ - "count" => $object->getLikesCount(), - "items" => [] - ]; - - $likers = array_slice(iterator_to_array($object->getLikers(1, $offset + $count)), $offset); - - foreach($likers as $liker) { - 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; - } -} +requireUser(); + $this->willExecuteWriteAction(); + + $postable = null; + switch ($type) { + case "post": + $post = (new PostsRepo())->getPostById($owner_id, $item_id); + $postable = $post; + break; + case "comment": + $comment = (new CommentsRepo())->get($item_id); + $postable = $comment; + break; + case "video": + $video = (new VideosRepo())->getByOwnerAndVID($owner_id, $item_id); + $postable = $video; + break; + case "photo": + $photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $item_id); + $postable = $photo; + break; + case "note": + $note = (new NotesRepo())->getNoteById($owner_id, $item_id); + $postable = $note; + break; + default: + $this->fail(100, "One of the parameters specified was missing or invalid: incorrect type"); + } + + if (is_null($postable) || $postable->isDeleted()) { + $this->fail(100, "One of the parameters specified was missing or invalid: object not found"); + } + + if (!$postable->canBeViewedBy($this->getUser() ?? null)) { + $this->fail(2, "Access to postable denied"); + } + + $postable->setLike(true, $this->getUser()); + + return (object) [ + "likes" => $postable->getLikesCount(), + ]; + } + + public function delete(string $type, int $owner_id, int $item_id): object + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $postable = null; + switch ($type) { + case "post": + $post = (new PostsRepo())->getPostById($owner_id, $item_id); + $postable = $post; + break; + case "comment": + $comment = (new CommentsRepo())->get($item_id); + $postable = $comment; + break; + case "video": + $video = (new VideosRepo())->getByOwnerAndVID($owner_id, $item_id); + $postable = $video; + break; + case "photo": + $photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $item_id); + $postable = $photo; + break; + case "note": + $note = (new NotesRepo())->getNoteById($owner_id, $item_id); + $postable = $note; + break; + default: + $this->fail(100, "One of the parameters specified was missing or invalid: incorrect type"); + } + + if (is_null($postable) || $postable->isDeleted()) { + $this->fail(100, "One of the parameters specified was missing or invalid: object not found"); + } + + if (!$postable->canBeViewedBy($this->getUser() ?? null)) { + $this->fail(2, "Access to postable denied"); + } + + if (!is_null($postable)) { + $postable->setLike(false, $this->getUser()); + + return (object) [ + "likes" => $postable->getLikesCount(), + ]; + } + } + + public function isLiked(int $user_id, string $type, int $owner_id, int $item_id): object + { + $this->requireUser(); + + $user = (new UsersRepo())->get($user_id); + + if (is_null($user) || $user->isDeleted()) { + $this->fail(100, "One of the parameters specified was missing or invalid: user not found"); + } + + if (!$user->canBeViewedBy($this->getUser())) { + $this->fail(1984, "Access denied: you can't see this user"); + } + + $postable = null; + switch ($type) { + case "post": + $post = (new PostsRepo())->getPostById($owner_id, $item_id); + $postable = $post; + break; + case "comment": + $comment = (new CommentsRepo())->get($item_id); + $postable = $comment; + break; + case "video": + $video = (new VideosRepo())->getByOwnerAndVID($owner_id, $item_id); + $postable = $video; + break; + case "photo": + $photo = (new PhotosRepo())->getByOwnerAndVID($owner_id, $item_id); + $postable = $photo; + break; + case "note": + $note = (new NotesRepo())->getNoteById($owner_id, $item_id); + $postable = $note; + break; + default: + $this->fail(100, "One of the parameters specified was missing or invalid: incorrect type"); + } + + if (is_null($postable) || $postable->isDeleted()) { + $this->fail(100, "One of the parameters specified was missing or invalid: object not found"); + } + + if (!$postable->canBeViewedBy($this->getUser())) { + $this->fail(665, "Access to postable denied"); + } + + return (object) [ + "liked" => (int) $postable->hasLikeFrom($user), + "copied" => 0, + ]; + } + + public function getList(string $type, int $owner_id, int $item_id, bool $extended = false, int $offset = 0, int $count = 10, bool $skip_own = false) + { + $this->requireUser(); + + $object = null; + + switch ($type) { + case "post": + $object = (new PostsRepo())->getPostById($owner_id, $item_id); + break; + case "comment": + $object = (new CommentsRepo())->get($item_id); + break; + case "photo": + $object = (new PhotosRepo())->getByOwnerAndVID($owner_id, $item_id); + break; + case "video": + $object = (new VideosRepo())->getByOwnerAndVID($owner_id, $item_id); + break; + default: + $this->fail(58, "Invalid type"); + break; + } + + if (!$object || $object->isDeleted()) { + $this->fail(56, "Invalid postable"); + } + + if (!$object->canBeViewedBy($this->getUser())) { + $this->fail(665, "Access to postable denied"); + } + + $res = (object) [ + "count" => $object->getLikesCount(), + "items" => [], + ]; + + $likers = array_slice(iterator_to_array($object->getLikers(1, $offset + $count)), $offset); + + foreach ($likers as $liker) { + 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; + } +} diff --git a/VKAPI/Handlers/Messages.php b/VKAPI/Handlers/Messages.php index 6fc057e0..b3c4c1b8 100644 --- a/VKAPI/Handlers/Messages.php +++ b/VKAPI/Handlers/Messages.php @@ -1,5 +1,9 @@ - 0) - return NULL; - + if ($user_id === -1) { + if ($peer_id === -1) { + return null; + } elseif ($peer_id < 0) { + return null; + } elseif (($peer_id - 2000000000) > 0) { + return null; + } + return $peer_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(); - - $msgs = new MSGRepo; + + $msgs = new MSGRepo(); $ids = preg_split("%, ?%", $message_ids); $items = []; - foreach($ids as $id) { + foreach ($ids as $id) { $message = $msgs->get((int) $id); - if(!$message) + if (!$message) { 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; - + } + $author = $message->getSender()->getId() === $this->getUser()->getId() ? $message->getRecipient()->getId() : $message->getSender()->getId(); - $rMsg = new APIMsg; - + $rMsg = new APIMsg(); + $rMsg->id = $message->getId(); $rMsg->user_id = $author; $rMsg->from_id = $message->getSender()->getId(); @@ -51,167 +57,186 @@ final class Messages extends VKAPIRequestHandler $rMsg->body = $message->getText(false); $rMsg->text = $message->getText(false); $rMsg->emoji = true; - - if($preview_length > 0) + + if ($preview_length > 0) { $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; } - + return (object) [ "count" => sizeof($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, - string $attachment = "") # интересно почему не attachments - { + + public 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, + string $attachment = "" + ) { # интересно почему не attachments $this->requireUser(); $this->willExecuteWriteAction(); - if($forGodSakePleaseDoNotReportAboutMyOnlineActivity == 0) - { + if ($forGodSakePleaseDoNotReportAboutMyOnlineActivity == 0) { $this->getUser()->updOnline($this->getPlatform()); } - - if($chat_id !== -1) + + if ($chat_id !== -1) { $this->fail(946, "Chats are not implemented"); - else if($sticker_id !== -1) + } elseif ($sticker_id !== -1) { $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"); - + } + # lol recursion - if(!empty($user_ids)) { + if (!empty($user_ids)) { $rIds = []; $ids = preg_split("%, ?%", $user_ids); - if(sizeof($ids) > 100) + if (sizeof($ids) > 100) { $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->willExecuteWriteAction(); - - $msgs = new MSGRepo; + + $msgs = new MSGRepo(); $ids = preg_split("%, ?%", $message_ids); $items = []; - foreach($ids as $id) { + foreach ($ids as $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; - + } + $message->delete(); $items[$id] = 1; } - + return (object) $items; } - - function restore(int $message_id): int + + public function restore(int $message_id): int { $this->requireUser(); $this->willExecuteWriteAction(); - - $msg = (new MSGRepo)->get($message_id); - if(!$msg) + + $msg = (new MSGRepo())->get($message_id); + if (!$msg) { return 0; - else if($msg->getSender()->getId() !== $this->getUser()->getId()) + } elseif ($msg->getSender()->getId() !== $this->getUser()->getId()) { return 0; - + } + $msg->undelete(); 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(); - - $convos = (new MSGRepo)->getCorrespondencies($this->getUser(), -1, $count, $offset); - $convosCount = (new MSGRepo)->getCorrespondenciesCount($this->getUser()); + + $convos = (new MSGRepo())->getCorrespondencies($this->getUser(), -1, $count, $offset); + $convosCount = (new MSGRepo())->getCorrespondenciesCount($this->getUser()); $list = []; $users = []; - foreach($convos as $convo) { + foreach ($convos as $convo) { $correspondents = $convo->getCorrespondents(); - if($correspondents[0]->getId() === $this->getUser()->getId()) + if ($correspondents[0]->getId() === $this->getUser()->getId()) { $peer = $correspondents[1]; - else + } else { $peer = $correspondents[0]; - + } + $lastMessage = $convo->getPreviewMessage(); - - $listConvo = new APIConvo; + + $listConvo = new APIConvo(); $listConvo->peer = [ "id" => $peer->getId(), "type" => "user", "local_id" => $peer->getId(), ]; - + $canWrite = $peer->getSubscriptionStatus($this->getUser()) === 3; $listConvo->can_write = [ "allowed" => $canWrite, ]; - - $lastMessagePreview = NULL; - if(!is_null($lastMessage)) { + + $lastMessagePreview = null; + if (!is_null($lastMessage)) { $listConvo->last_message_id = $lastMessage->getId(); - - if($lastMessage->getSender()->getId() === $this->getUser()->getId()) + + if ($lastMessage->getSender()->getId() === $this->getUser()->getId()) { $author = $lastMessage->getRecipient()->getId(); - else + } else { $author = $lastMessage->getSender()->getId(); - - $lastMessagePreview = new APIMsg; + } + + $lastMessagePreview = new APIMsg(); $lastMessagePreview->id = $lastMessage->getId(); $lastMessagePreview->user_id = $author; $lastMessagePreview->from_id = $lastMessage->getSender()->getId(); @@ -221,19 +246,19 @@ final class Messages extends VKAPIRequestHandler $lastMessagePreview->body = $lastMessage->getText(false); $lastMessagePreview->text = $lastMessage->getText(false); $lastMessagePreview->emoji = true; - - if($extended == 1) { + + if ($extended == 1) { $users[] = $author; } } - + $list[] = [ "conversation" => $listConvo, "last_message" => $lastMessagePreview, ]; } - - if($extended == 0){ + + if ($extended == 0) { return (object) [ "count" => $convosCount, "items" => $list, @@ -245,12 +270,12 @@ final class Messages extends VKAPIRequestHandler return (object) [ "count" => $convosCount, "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(); @@ -258,21 +283,23 @@ final class Messages extends VKAPIRequestHandler $output = [ "count" => 0, - "items" => [] + "items" => [], ]; $userslist = []; - foreach($peers as $peer) { - if(key($peers) > 100) + foreach ($peers as $peer) { + if (key($peers) > 100) { 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"); + } - $user = (new USRRepo)->get((int) $peer); + $user = (new USRRepo())->get((int) $peer); - if($user) { + if ($user) { $dialogue = new Correspondence($this->getUser(), $user); $iterator = $dialogue->getMessages(Correspondence::CAP_BEHAVIOUR_START_MESSAGE_ID, 0, 1, 0, false); $msg = $iterator[0]->unwrap(); // шоб удобнее было @@ -280,7 +307,7 @@ final class Messages extends VKAPIRequestHandler "peer" => [ "id" => $user->getId(), "type" => "user", - "local_id" => $user->getId() + "local_id" => $user->getId(), ], "last_message_id" => $msg->id, "in_read" => $msg->id, @@ -295,41 +322,43 @@ final class Messages extends VKAPIRequestHandler "is_marked_unread" => $iterator[0]->isUnread(), "important" => false, // целестора когда релиз "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(); } } - if($extended == 1) { + if ($extended == 1) { $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']); 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(); - - 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"); - - $peer = (new USRRepo)->get($user_id); - if(!$peer) + } + + $peer = (new USRRepo())->get($user_id); + if (!$peer) { $this->fail(1, "ошибка про то что пира нет"); - + } + $results = []; $dialogue = new Correspondence($this->getUser(), $peer); $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. - # UPDATE: the issue seems to be caused by debug mode and json_encode (bruh_encode). ~~Dorothy - - $rMsg = new APIMsg; + # UPDATE: the issue seems to be caused by debug mode and json_encode (bruh_encode). ~~Dorothy + + $rMsg = new APIMsg(); $rMsg->id = $msgU->id; $rMsg->user_id = $msgU->sender_id === $this->getUser()->getId() ? $msgU->recipient_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->text = $message->getText(false); $rMsg->emoji = true; - + $results[] = $rMsg; } - + $output = [ "count" => sizeof($results), "items" => $results, @@ -356,100 +385,111 @@ final class Messages extends VKAPIRequestHandler 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(); - + $res = [ "history" => [], "messages" => [], "profiles" => [], "new_pts" => 0, ]; - + $manager = SignalManager::i(); - $events = $manager->getHistoryFor($this->getUser()->getId(), $ts === -1 ? NULL : $ts, min($events_limit, $msgs_limit)); - foreach($events as $event) { - if(!($event instanceof NewMessageEvent)) + $events = $manager->getHistoryFor($this->getUser()->getId(), $ts === -1 ? null : $ts, min($events_limit, $msgs_limit)); + foreach ($events as $event) { + if (!($event instanceof NewMessageEvent)) { continue; - + } + $message = $this->getById((string) $event->getLongPoolSummary()->message["uuid"], $preview_length, 1)->items[0]; - if(!$message) + if (!$message) { continue; - + } + $res["messages"][] = $message; $res["history"][] = $event->getVKAPISummary($this->getUser()->getId()); } - + $res["messages"] = [ "count" => sizeof($res["messages"]), "items" => $res["messages"], ]; 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(); - - if($group_id > 0) + + if ($group_id > 0) { $this->fail(-151, "Not implemented"); - + } + $url = "http" . (ovk_is_ssl() ? "s" : "") . "://$_SERVER[HTTP_HOST]/nim" . $this->getUser()->getId(); $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 = [ "key" => $key, "server" => $url, "ts" => time(), ]; - - if($need_pts === 1) + + if ($need_pts === 1) { $res["pts"] = -1; - + } + 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->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."); + } - if(!$msg || $msg->isDeleted()) + if (!$msg || $msg->isDeleted()) { $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"); - - if(!empty($message)) + } + + if (!empty($message)) { $msg->setContent($message); + } $msg->setEdited(time()); $msg->save(true); - if(!empty($attachment)) { + if (!empty($attachment)) { $attachs = parseAttachments($attachment); $newAttachmentsCount = sizeof($attachs); $postsAttachments = iterator_to_array($msg->getChildren()); - if(sizeof($postsAttachments) >= 10) + if (sizeof($postsAttachments) >= 10) { $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"); + } - foreach($attachs as $attach) { - if($attach && !$attach->isDeleted() && $attach->getOwner()->getId() == $this->getUser()->getId()) + foreach ($attachs as $attach) { + if ($attach && !$attach->isDeleted() && $attach->getOwner()->getId() == $this->getUser()->getId()) { $msg->attach($attach); - else + } else { $this->fail(52, "One of the attachments is invalid"); + } } } diff --git a/VKAPI/Handlers/Newsfeed.php b/VKAPI/Handlers/Newsfeed.php index 557a3724..346d5312 100644 --- a/VKAPI/Handlers/Newsfeed.php +++ b/VKAPI/Handlers/Newsfeed.php @@ -1,254 +1,273 @@ -requireUser(); - - if($forGodSakePleaseDoNotReportAboutMyOnlineActivity == 0) - { - $this->getUser()->updOnline($this->getPlatform()); - } - - $id = $this->getUser()->getId(); - $subs = DatabaseConnection::i() - ->getContext() - ->table("subscriptions") - ->where("follower", $id); - $ids = array_map(function($rel) { - return $rel->target * ($rel->model === "openvk\Web\Models\Entities\User" ? 1 : -1); - }, iterator_to_array($subs)); - $ids[] = $this->getUser()->getId(); - - $posts = DatabaseConnection::i() - ->getContext() - ->table("posts") - ->select("id") - ->where("wall IN (?)", $ids) - ->where("deleted", 0) - ->where("suggested", 0) - ->where("id < (?)", empty($start_from) ? PHP_INT_MAX : $start_from) - ->where("? <= created", empty($start_time) ? 0 : $start_time) - ->where("? >= created", empty($end_time) ? PHP_INT_MAX : $end_time) - ->order("created DESC"); - - $rposts = []; - foreach($posts->page((int) ($offset + 1), $count) as $post) - $rposts[] = (new PostsRepo)->get($post->id)->getPrettyId(); - - $response = (new Wall)->getById(implode(',', $rposts), $extended, $fields, $this->getUser()); - $response->next_from = end(end($posts->page((int) ($offset + 1), $count))); // ну и костыли пиздец конечно) - - return $response; - } - - 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) - { - $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`)"; - $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($this->getUser()->getNsfwTolerance() === User::NSFW_INTOLERANT) - $queryBase .= " AND `nsfw` = 0"; - - 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) { - $imploded_ids = implode("', '", $ignored_sources_ids); - $queryBase .= " AND `posts`.`wall` NOT IN ('$imploded_ids')"; - } - } - - $start_from = empty($start_from) ? PHP_INT_MAX : $start_from; - $start_time = empty($start_time) ? 0 : $start_time; - $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 = []; - $ids = []; - if($rss == 1) { - $channel = new \Bhaktaraz\RSSGenerator\Channel(); - $channel->title("Global Feed — " . OPENVK_ROOT_CONF['openvk']['appearance']['name']) - ->description('OVK Global feed') - ->url(ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/feed/all"); - - foreach($posts as $item) { - $post = (new PostsRepo)->get($item->id); - if(!$post || $post->isDeleted()) { - continue; - } - - $output = $post->toRss(); - $output->appendTo($channel); - } - - return $channel; - } - - foreach($posts as $post) { - $rposts[] = (new PostsRepo)->get($post->id)->getPrettyId(); - $ids[] = $post->id; - } - - $response = (new Wall)->getById(implode(',', $rposts), $extended, $fields, $this->getUser()); - $response->next_from = end($ids); - - return $response; - } - - 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) - { - $this->requireUser(); - - switch($feed_type) { - case 'top': - return $this->getGlobal($fields, $start_from, $start_time, $end_time, $offset, $count, $extended, $return_banned); - break; - default: - return $this->get($fields, $start_from, $start_time, $end_time, $offset, $count, $extended); - break; - } - } - - function getBanned(int $extended = 0, string $fields = "", string $name_case = "nom", int $merge = 0): object - { - $this->requireUser(); - - $offset = 0; - $count = OPENVK_ROOT_CONF['openvk']['preferences']['newsfeed']['ignoredSourcesLimit'] ?? 50; - $banned = $this->getUser()->getIgnoredSources($offset, $count, ($extended != 1)); - $return_object = (object) [ - 'groups' => [], - 'members' => [], - ]; - - if($extended == 0) { - foreach($banned as $ban) { - if($ban > 0) - $return_object->members[] = $ban; - else - $return_object->groups[] = $ban; - } - } else { - if($merge == 1) { - $return_object = (object) [ - 'count' => sizeof($banned), - 'items' => [], - ]; - - foreach($banned as $ban) { - $return_object->items[] = $ban->toVkApiStruct($this->getUser(), $fields); - } - } else { - $return_object = (object) [ - 'groups' => [], - 'profiles' => [], - ]; - - foreach($banned as $ban) { - if($ban->getRealId() > 0) - $return_object->profiles[] = $ban->toVkApiStruct($this->getUser(), $fields); - else - $return_object->groups[] = $ban->toVkApiStruct($this->getUser(), $fields); - } - } - } - - return $return_object; - } - - function addBan(string $user_ids = "", string $group_ids = "") - { - $this->requireUser(); - $this->willExecuteWriteAction(); - - # Formatting input ids - if(!empty($user_ids)) { - $user_ids = array_map(function($el) { - return (int)$el; - }, explode(',', $user_ids)); - $user_ids = array_unique($user_ids); - } else - $user_ids = []; - - if(!empty($group_ids)) { - $group_ids = array_map(function($el) { - return abs((int)$el) * -1; - }, explode(',', $group_ids)); - $group_ids = array_unique($group_ids); - } else - $group_ids = []; - - $ids = array_merge($user_ids, $group_ids); - if(sizeof($ids) < 1) - return 0; - - if(sizeof($ids) > 10) - $this->fail(-10, "Limit of 'ids' is 10"); - - $config_limit = OPENVK_ROOT_CONF['openvk']['preferences']['newsfeed']['ignoredSourcesLimit'] ?? 50; - $user_ignores = $this->getUser()->getIgnoredSourcesCount(); - if(($user_ignores + sizeof($ids)) > $config_limit) { - $this->fail(-50, "Ignoring limit exceeded"); - } - - $entities = get_entities($ids); - $successes = 0; - foreach($entities as $entity) { - if(!$entity || $entity->getRealId() === $this->getUser()->getRealId() || $entity->isHideFromGlobalFeedEnabled() || $entity->isIgnoredBy($this->getUser())) continue; - - $entity->addIgnore($this->getUser()); - $successes += 1; - } - - return 1; - } - - function deleteBan(string $user_ids = "", string $group_ids = "") - { - $this->requireUser(); - $this->willExecuteWriteAction(); - - if(!empty($user_ids)) { - $user_ids = array_map(function($el) { - return (int)$el; - }, explode(',', $user_ids)); - $user_ids = array_unique($user_ids); - } else - $user_ids = []; - - if(!empty($group_ids)) { - $group_ids = array_map(function($el) { - return abs((int)$el) * -1; - }, explode(',', $group_ids)); - $group_ids = array_unique($group_ids); - } else - $group_ids = []; - - $ids = array_merge($user_ids, $group_ids); - 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; - } -} +requireUser(); + + if ($forGodSakePleaseDoNotReportAboutMyOnlineActivity == 0) { + $this->getUser()->updOnline($this->getPlatform()); + } + + $id = $this->getUser()->getId(); + $subs = DatabaseConnection::i() + ->getContext() + ->table("subscriptions") + ->where("follower", $id); + $ids = array_map(function ($rel) { + return $rel->target * ($rel->model === "openvk\Web\Models\Entities\User" ? 1 : -1); + }, iterator_to_array($subs)); + $ids[] = $this->getUser()->getId(); + + $posts = DatabaseConnection::i() + ->getContext() + ->table("posts") + ->select("id") + ->where("wall IN (?)", $ids) + ->where("deleted", 0) + ->where("suggested", 0) + ->where("id < (?)", empty($start_from) ? PHP_INT_MAX : $start_from) + ->where("? <= created", empty($start_time) ? 0 : $start_time) + ->where("? >= created", empty($end_time) ? PHP_INT_MAX : $end_time) + ->order("created DESC"); + + $rposts = []; + foreach ($posts->page((int) ($offset + 1), $count) as $post) { + $rposts[] = (new PostsRepo())->get($post->id)->getPrettyId(); + } + + $response = (new Wall())->getById(implode(',', $rposts), $extended, $fields, $this->getUser()); + $response->next_from = end(end($posts->page((int) ($offset + 1), $count))); // ну и костыли пиздец конечно) + + return $response; + } + + 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) + { + $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`)"; + $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 ($this->getUser()->getNsfwTolerance() === User::NSFW_INTOLERANT) { + $queryBase .= " AND `nsfw` = 0"; + } + + 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) { + $imploded_ids = implode("', '", $ignored_sources_ids); + $queryBase .= " AND `posts`.`wall` NOT IN ('$imploded_ids')"; + } + } + + $start_from = empty($start_from) ? PHP_INT_MAX : $start_from; + $start_time = empty($start_time) ? 0 : $start_time; + $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 = []; + $ids = []; + if ($rss == 1) { + $channel = new \Bhaktaraz\RSSGenerator\Channel(); + $channel->title("Global Feed — " . OPENVK_ROOT_CONF['openvk']['appearance']['name']) + ->description('OVK Global feed') + ->url(ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/feed/all"); + + foreach ($posts as $item) { + $post = (new PostsRepo())->get($item->id); + if (!$post || $post->isDeleted()) { + continue; + } + + $output = $post->toRss(); + $output->appendTo($channel); + } + + return $channel; + } + + foreach ($posts as $post) { + $rposts[] = (new PostsRepo())->get($post->id)->getPrettyId(); + $ids[] = $post->id; + } + + $response = (new Wall())->getById(implode(',', $rposts), $extended, $fields, $this->getUser()); + $response->next_from = end($ids); + + return $response; + } + + 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) + { + $this->requireUser(); + + switch ($feed_type) { + case 'top': + return $this->getGlobal($fields, $start_from, $start_time, $end_time, $offset, $count, $extended, $return_banned); + break; + default: + return $this->get($fields, $start_from, $start_time, $end_time, $offset, $count, $extended); + break; + } + } + + public function getBanned(int $extended = 0, string $fields = "", string $name_case = "nom", int $merge = 0): object + { + $this->requireUser(); + + $offset = 0; + $count = OPENVK_ROOT_CONF['openvk']['preferences']['newsfeed']['ignoredSourcesLimit'] ?? 50; + $banned = $this->getUser()->getIgnoredSources($offset, $count, ($extended != 1)); + $return_object = (object) [ + 'groups' => [], + 'members' => [], + ]; + + if ($extended == 0) { + foreach ($banned as $ban) { + if ($ban > 0) { + $return_object->members[] = $ban; + } else { + $return_object->groups[] = $ban; + } + } + } else { + if ($merge == 1) { + $return_object = (object) [ + 'count' => sizeof($banned), + 'items' => [], + ]; + + foreach ($banned as $ban) { + $return_object->items[] = $ban->toVkApiStruct($this->getUser(), $fields); + } + } else { + $return_object = (object) [ + 'groups' => [], + 'profiles' => [], + ]; + + foreach ($banned as $ban) { + if ($ban->getRealId() > 0) { + $return_object->profiles[] = $ban->toVkApiStruct($this->getUser(), $fields); + } else { + $return_object->groups[] = $ban->toVkApiStruct($this->getUser(), $fields); + } + } + } + } + + return $return_object; + } + + public function addBan(string $user_ids = "", string $group_ids = "") + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + # Formatting input ids + if (!empty($user_ids)) { + $user_ids = array_map(function ($el) { + return (int) $el; + }, explode(',', $user_ids)); + $user_ids = array_unique($user_ids); + } else { + $user_ids = []; + } + + if (!empty($group_ids)) { + $group_ids = array_map(function ($el) { + return abs((int) $el) * -1; + }, explode(',', $group_ids)); + $group_ids = array_unique($group_ids); + } else { + $group_ids = []; + } + + $ids = array_merge($user_ids, $group_ids); + if (sizeof($ids) < 1) { + return 0; + } + + if (sizeof($ids) > 10) { + $this->fail(-10, "Limit of 'ids' is 10"); + } + + $config_limit = OPENVK_ROOT_CONF['openvk']['preferences']['newsfeed']['ignoredSourcesLimit'] ?? 50; + $user_ignores = $this->getUser()->getIgnoredSourcesCount(); + if (($user_ignores + sizeof($ids)) > $config_limit) { + $this->fail(-50, "Ignoring limit exceeded"); + } + + $entities = get_entities($ids); + $successes = 0; + foreach ($entities as $entity) { + if (!$entity || $entity->getRealId() === $this->getUser()->getRealId() || $entity->isHideFromGlobalFeedEnabled() || $entity->isIgnoredBy($this->getUser())) { + continue; + } + + $entity->addIgnore($this->getUser()); + $successes += 1; + } + + return 1; + } + + public function deleteBan(string $user_ids = "", string $group_ids = "") + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + if (!empty($user_ids)) { + $user_ids = array_map(function ($el) { + return (int) $el; + }, explode(',', $user_ids)); + $user_ids = array_unique($user_ids); + } else { + $user_ids = []; + } + + if (!empty($group_ids)) { + $group_ids = array_map(function ($el) { + return abs((int) $el) * -1; + }, explode(',', $group_ids)); + $group_ids = array_unique($group_ids); + } else { + $group_ids = []; + } + + $ids = array_merge($user_ids, $group_ids); + 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; + } +} diff --git a/VKAPI/Handlers/Notes.php b/VKAPI/Handlers/Notes.php index 620877c9..cdf5aa45 100644 --- a/VKAPI/Handlers/Notes.php +++ b/VKAPI/Handlers/Notes.php @@ -1,5 +1,9 @@ -requireUser(); $this->willExecuteWriteAction(); - $note = new Note; + $note = new Note(); $note->setOwner($this->getUser()->getId()); $note->setCreated(time()); $note->setName($title); @@ -25,31 +29,37 @@ final class Notes extends VKAPIRequestHandler 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->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"); - - if($note->isDeleted()) + } + + if ($note->isDeleted()) { $this->fail(189, "Note is deleted"); - - if($note->getOwner()->isDeleted()) + } + + if ($note->getOwner()->isDeleted()) { $this->fail(403, "Owner is deleted"); + } - if(!$note->canBeViewedBy($this->getUser())) + if (!$note->canBeViewedBy($this->getUser())) { $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"); + } - if(empty($message) && empty($attachments)) + if (empty($message) && empty($attachments)) { $this->fail(100, "Required parameter 'message' missing."); + } - $comment = new Comment; + $comment = new Comment(); $comment->setOwner($this->getUser()->getId()); $comment->setModel(get_class($note)); $comment->setTarget($note->getId()); @@ -57,43 +67,49 @@ final class Notes extends VKAPIRequestHandler $comment->setCreated(time()); $comment->save(); - if(!empty($attachments)) { + if (!empty($attachments)) { $attachmentsArr = explode(",", $attachments); - if(sizeof($attachmentsArr) > 10) + if (sizeof($attachmentsArr) > 10) { $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"; - elseif(str_contains($attac, "video")) + } elseif (str_contains($attac, "video")) { $attachmentType = "video"; - else + } else { $this->fail(205, "Unknown attachment type"); + } $attachment = str_replace($attachmentType, "", $attac); - $attachmentOwner = (int)explode("_", $attachment)[0]; - $attachmentId = (int)end(explode("_", $attachment)); + $attachmentOwner = (int) explode("_", $attachment)[0]; + $attachmentId = (int) end(explode("_", $attachment)); - $attacc = NULL; + $attacc = null; - if($attachmentType == "photo") { - $attacc = (new PhotosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId); - if(!$attacc || $attacc->isDeleted()) + if ($attachmentType == "photo") { + $attacc = (new PhotosRepo())->getByOwnerAndVID($attachmentOwner, $attachmentId); + if (!$attacc || $attacc->isDeleted()) { $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"); - + } + $comment->attach($attacc); - } elseif($attachmentType == "video") { - $attacc = (new VideosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId); - if(!$attacc || $attacc->isDeleted()) + } elseif ($attachmentType == "video") { + $attacc = (new VideosRepo())->getByOwnerAndVID($attachmentOwner, $attachmentId); + if (!$attacc || $attacc->isDeleted()) { $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"); + } $comment->attach($attacc); } @@ -103,87 +119,96 @@ final class Notes extends VKAPIRequestHandler return $comment->getId(); } - function delete(string $note_id) + public function delete(string $note_id) { $this->requireUser(); $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"); - - if(!$note->canBeModifiedBy($this->getUser())) + } + + if (!$note->canBeModifiedBy($this->getUser())) { $this->fail(15, "Access to note denied"); - + } + $note->delete(); 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->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"); - - if($note->isDeleted()) + } + + if ($note->isDeleted()) { $this->fail(189, "Note is deleted"); + } - if(!$note->canBeModifiedBy($this->getUser())) + if (!$note->canBeModifiedBy($this->getUser())) { $this->fail(403, "No access"); + } - !empty($title) ? $note->setName($title) : NULL; - !empty($text) ? $note->setSource($text) : NULL; + !empty($title) ? $note->setName($title) : null; + !empty($text) ? $note->setSource($text) : null; - $note->setCached_Content(NULL); + $note->setCached_Content(null); $note->setEdited(time()); $note->save(); 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(); - $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"); - - 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"); - - 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) [ - "count" => (new NotesRepo)->getUserNotesCount((new UsersRepo)->get($user_id)), - "notes" => [] + "count" => (new NotesRepo())->getUserNotesCount((new UsersRepo())->get($user_id)), + "notes" => [], ]; - - foreach($notes as $note) { - if($note->isDeleted()) continue; - + + foreach ($notes as $note) { + if ($note->isDeleted()) { + continue; + } + $nodez->notes[] = $note->toVkApiStruct(); } } else { $notes = explode(',', $note_ids); - foreach($notes as $note) - { + foreach ($notes as $note) { $id = explode("_", $note); - + $items = []; - - $note = (new NotesRepo)->getNoteById((int)$id[0], (int)$id[1]); - if($note && !$note->isDeleted()) { + + $note = (new NotesRepo())->getNoteById((int) $id[0], (int) $id[1]); + if ($note && !$note->isDeleted()) { $nodez->notes[] = $note->toVkApiStruct(); } } @@ -192,69 +217,79 @@ final class Notes extends VKAPIRequestHandler 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(); - $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"); - - if($note->isDeleted()) + } + + if ($note->isDeleted()) { $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"); + } - 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"); + } - if(!$note->canBeViewedBy($this->getUser())) + if (!$note->canBeViewedBy($this->getUser())) { $this->fail(15, "Access to note denied"); + } 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(); - $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"); - - if($note->isDeleted()) + } + + if ($note->isDeleted()) { $this->fail(189, "Note is deleted"); - - if(!$note->getOwner()) + } + + if (!$note->getOwner()) { $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"); + } - if(!$note->canBeViewedBy($this->getUser())) + if (!$note->canBeViewedBy($this->getUser())) { $this->fail(15, "Access to note denied"); - + } + $arr = (object) [ - "count" => $note->getCommentsCount(), + "count" => $note->getCommentsCount(), "comments" => []]; $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); } return $arr; } - function getFriendsNotes(int $offset = 0, int $count = 0) + public function getFriendsNotes(int $offset = 0, int $count = 0) { $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"); } diff --git a/VKAPI/Handlers/Notifications.php b/VKAPI/Handlers/Notifications.php index 8a047f80..1114c306 100644 --- a/VKAPI/Handlers/Notifications.php +++ b/VKAPI/Handlers/Notifications.php @@ -1,62 +1,70 @@ -requireUser(); - $res = (object)[ + $res = (object) [ "items" => [], "profiles" => [], "groups" => [], - "last_viewed" => $this->getUser()->getNotificationOffset() + "last_viewed" => $this->getUser()->getNotificationOffset(), ]; - if($count > 100) + if ($count > 100) { $this->fail(125, "Count is too big"); + } - if(!eventdb()) + if (!eventdb()) { $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 = []; - foreach($notifs as $notif) { + foreach ($notifs as $notif) { $sxModel = $notif->getModel(1); - if(!method_exists($sxModel, "getAvatarUrl")) + if (!method_exists($sxModel, "getAvatarUrl")) { $sxModel = $notif->getModel(0); + } + - $tmpProfiles[] = $sxModel instanceof Club ? $sxModel->getId() * -1 : $sxModel->getId(); $res->items[] = $notif->toVkApiStruct(); } - foreach(array_unique($tmpProfiles) as $id) { - if($id > 0) { - $sxModel = (new Users)->get($id); - $result = (object)[ + foreach (array_unique($tmpProfiles) as $id) { + if ($id > 0) { + $sxModel = (new Users())->get($id); + $result = (object) [ "uid" => $sxModel->getId(), "first_name" => $sxModel->getFirstName(), "last_name" => $sxModel->getLastName(), "photo" => $sxModel->getAvatarUrl(), "photo_medium_rec" => $sxModel->getAvatarUrl("tiny"), - "screen_name" => $sxModel->getShortCode() + "screen_name" => $sxModel->getShortCode(), ]; $res->profiles[] = $result; } else { - $sxModel = (new Clubs)->get(abs($id)); + $sxModel = (new Clubs())->get(abs($id)); $result = $sxModel->toVkApiStruct($this->getUser()); $res->groups[] = $result; @@ -66,7 +74,7 @@ final class Notifications extends VKAPIRequestHandler return $res; } - function markAsViewed() + public function markAsViewed() { $this->requireUser(); $this->willExecuteWriteAction(); @@ -74,7 +82,7 @@ final class Notifications extends VKAPIRequestHandler try { $this->getUser()->updateNotificationOffset(); $this->getUser()->save(); - } catch(\Throwable $e) { + } catch (\Throwable $e) { return 0; } diff --git a/VKAPI/Handlers/Ovk.php b/VKAPI/Handlers/Ovk.php index a260f1c4..26c83e9e 100644 --- a/VKAPI/Handlers/Ovk.php +++ b/VKAPI/Handlers/Ovk.php @@ -1,15 +1,19 @@ - $this->userAuthorized(), @@ -17,58 +21,59 @@ final class Ovk extends VKAPIRequestHandler "version" => VKAPI_DECL_VER, ]; } - - function chickenWings(): string + + public function chickenWings(): string { 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); $response = (object) []; - if(in_array("statistics", $fields)) { - $usersStats = (new UsersRepo)->getStatistics(); - $clubsCount = (new ClubsRepo)->getCount(); - $postsCount = (new PostsRepo)->getCount(); + if (in_array("statistics", $fields)) { + $usersStats = (new UsersRepo())->getStatistics(); + $clubsCount = (new ClubsRepo())->getCount(); + $postsCount = (new PostsRepo())->getCount(); $response->statistics = (object) [ "users_count" => $usersStats->all, "online_users_count" => $usersStats->online, "active_users_count" => $usersStats->active, "groups_count" => $clubsCount, - "wall_posts_count" => $postsCount + "wall_posts_count" => $postsCount, ]; } - if(in_array("administrators", $fields)) { - $admins = iterator_to_array((new UsersRepo)->getInstanceAdmins()); - $adminsResponse = (new Users($this->getUser()))->get(implode(',', array_map(function($admin) { + if (in_array("administrators", $fields)) { + $admins = iterator_to_array((new UsersRepo())->getInstanceAdmins()); + $adminsResponse = (new Users($this->getUser()))->get(implode(',', array_map(function ($admin) { return $admin->getId(); }, $admins)), $admin_fields, 0, sizeof($admins)); $response->administrators = (object) [ "count" => sizeof($admins), - "items" => $adminsResponse + "items" => $adminsResponse, ]; } - if(in_array("popular_groups", $fields)) { - $popularClubs = iterator_to_array((new ClubsRepo)->getPopularClubs()); - $clubsResponse = (new Groups($this->getUser()))->getById(implode(',', array_map(function($entry) { + if (in_array("popular_groups", $fields)) { + $popularClubs = iterator_to_array((new ClubsRepo())->getPopularClubs()); + $clubsResponse = (new Groups($this->getUser()))->getById(implode(',', array_map(function ($entry) { return $entry->club->getId(); }, $popularClubs)), "", "members_count, " . $group_fields); $response->popular_groups = (object) [ "count" => sizeof($popularClubs), - "items" => $clubsResponse + "items" => $clubsResponse, ]; } - if(in_array("links", $fields)) + if (in_array("links", $fields)) { $response->links = (object) [ "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; } diff --git a/VKAPI/Handlers/Pay.php b/VKAPI/Handlers/Pay.php index e5fb93a7..8e6ba24e 100644 --- a/VKAPI/Handlers/Pay.php +++ b/VKAPI/Handlers/Pay.php @@ -1,42 +1,49 @@ -fail(4, "Invalid marketing id"); + } } catch (\SodiumException $e) { $this->fail(4, "Invalid marketing id"); } - + 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(); - + $app = (new Applications())->get($app_id); - if(!$app) + if (!$app) { $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"); - + } + [$time, $signature] = explode(",", $signature); try { $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"); + } } catch (\SodiumException $e) { $this->fail(4, "Invalid order"); } - + return true; } -} \ No newline at end of file +} diff --git a/VKAPI/Handlers/Photos.php b/VKAPI/Handlers/Photos.php index 1ae99faf..1863daaf 100644 --- a/VKAPI/Handlers/Photos.php +++ b/VKAPI/Handlers/Photos.php @@ -1,4 +1,7 @@ -fail(121, "Incorrect hash"); + } [$up, $image, $group] = explode("|", $photo); $imagePath = __DIR__ . "/../../tmp/api-storage/photos/$up" . "_$image.oct"; - if(!file_exists($imagePath)) + if (!file_exists($imagePath)) { $this->fail(10, "Invalid image"); + } return $imagePath; } - function getOwnerPhotoUploadServer(int $owner_id = 0): object + public function getOwnerPhotoUploadServer(int $owner_id = 0): object { $this->requireUser(); - if($owner_id < 0) { - $club = (new Clubs)->get(abs($owner_id)); - if(!$club) - $this->fail(0404, "Club not found"); - else if(!$club->canBeModifiedBy($this->getUser())) + if ($owner_id < 0) { + $club = (new Clubs())->get(abs($owner_id)); + if (!$club) { + $this->fail(0o404, "Club not found"); + } elseif (!$club->canBeModifiedBy($this->getUser())) { $this->fail(200, "Access: Club can't be 'written' by user"); + } } 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); - if($group == 0) { - $user = (new \openvk\Web\Models\Repositories\Users)->get((int) $uploader); - $album = (new Albums)->getUserAvatarAlbum($user); + if ($group == 0) { + $user = (new \openvk\Web\Models\Repositories\Users())->get((int) $uploader); + $album = (new Albums())->getUserAvatarAlbum($user); } else { - $club = (new Clubs)->get((int) $group); - $album = (new Albums)->getClubAvatarAlbum($club); + $club = (new Clubs())->get((int) $group); + $album = (new Albums())->getClubAvatarAlbum($club); } try { - $avatar = new Photo; + $avatar = new Photo(); $avatar->setOwner((int) $uploader); $avatar->setDescription("Profile photo"); $avatar->setCreated(time()); @@ -88,30 +94,31 @@ final class Photos extends VKAPIRequestHandler $avatar->save(); $album->addPhoto($avatar); unlink($imagePath); - } catch(ImageException | InvalidStateException $e) { + } catch (ImageException | InvalidStateException $e) { unlink($imagePath); $this->fail(129, "Invalid image file"); } return (object) [ - "photo_hash" => NULL, + "photo_hash" => null, "photo_src" => $avatar->getURL(), ]; } - function getWallUploadServer(?int $group_id = NULL): object + public function getWallUploadServer(?int $group_id = null): object { $this->requireUser(); - $album = NULL; - if(!is_null($group_id)) { - $club = (new Clubs)->get(abs($group_id)); - if(!$club) - $this->fail(0404, "Club not found"); - else if(!$club->canBeModifiedBy($this->getUser())) + $album = null; + if (!is_null($group_id)) { + $club = (new Clubs())->get(abs($group_id)); + if (!$club) { + $this->fail(0o404, "Club not found"); + } elseif (!$club->canBeModifiedBy($this->getUser())) { $this->fail(200, "Access: Club can't be 'written' by user"); + } } else { - $album = (new Albums)->getUserWallAlbum($this->getUser()); + $album = (new Albums())->getUserWallAlbum($this->getUser()); } 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); - if($group_id != $group) + if ($group_id != $group) { $this->fail(8, "group_id doesn't match"); + } - $album = NULL; - if($group_id != 0) { - $uploader = (new \openvk\Web\Models\Repositories\Users)->get((int) $uploader); - $album = (new Albums)->getUserWallAlbum($uploader); + $album = null; + if ($group_id != 0) { + $uploader = (new \openvk\Web\Models\Repositories\Users())->get((int) $uploader); + $album = (new Albums())->getUserWallAlbum($uploader); } try { - $photo = new Photo; + $photo = new Photo(); $photo->setOwner((int) $uploader); $photo->setCreated(time()); $photo->setFile([ @@ -142,25 +150,27 @@ final class Photos extends VKAPIRequestHandler "error" => 0, ]); - if (!is_null($caption)) + if (!is_null($caption)) { $photo->setDescription($caption); + } $photo->save(); unlink($imagePath); - } catch(ImageException | InvalidStateException $e) { + } catch (ImageException | InvalidStateException $e) { unlink($imagePath); $this->fail(129, "Invalid image file"); } - if(!is_null($album)) + if (!is_null($album)) { $album->addPhoto($photo); + } return [ $photo->toVkApiStruct(), ]; } - function getUploadServer(?int $album_id = NULL): object + public function getUploadServer(?int $album_id = null): object { $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(); $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"); + } - $album = NULL; - if($album_id != 0) { - $album_ = (new Albums)->get($album_id); - if(!$album_) - $this->fail(0404, "Invalid album"); - else if(!$album_->canBeModifiedBy($this->getUser())) + $album = null; + if ($album_id != 0) { + $album_ = (new Albums())->get($album_id); + if (!$album_) { + $this->fail(0o404, "Invalid album"); + } elseif (!$album_->canBeModifiedBy($this->getUser())) { $this->fail(15, "Access: Album can't be 'written' by user"); + } $album = $album_; } $pList = json_decode($photos_list); $imagePaths = []; - foreach($pList as $pDesc) + foreach ($pList as $pDesc) { $imagePaths[] = __DIR__ . "/../../tmp/api-storage/photos/$pDesc->keyholder" . "_$pDesc->resource.oct"; + } $images = []; try { - foreach($imagePaths as $imagePath) { - $photo = new Photo; + foreach ($imagePaths as $imagePath) { + $photo = new Photo(); $photo->setOwner($this->getUser()->getId()); $photo->setCreated(time()); $photo->setFile([ @@ -207,20 +220,23 @@ final class Photos extends VKAPIRequestHandler "error" => 0, ]); - if (!is_null($caption)) + if (!is_null($caption)) { $photo->setDescription($caption); + } $photo->save(); unlink($imagePath); - if(!is_null($album)) + if (!is_null($album)) { $album->addPhoto($photo); + } $images[] = $photo->toVkApiStruct(); } - } catch(ImageException | InvalidStateException $e) { - foreach($imagePaths as $imagePath) + } catch (ImageException | InvalidStateException $e) { + foreach ($imagePaths as $imagePath) { unlink($imagePath); + } $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->willExecuteWriteAction(); - if($group_id != 0) { - $club = (new Clubs)->get((int) $group_id); + if ($group_id != 0) { + $club = (new Clubs())->get((int) $group_id); - if(!$club || !$club->canBeModifiedBy($this->getUser())) { + if (!$club || !$club->canBeModifiedBy($this->getUser())) { $this->fail(20, "Invalid club"); } } - $album = new Album; + $album = new Album(); $album->setOwner(isset($club) ? $club->getId() * -1 : $this->getUser()->getId()); $album->setName($title); $album->setDescription($description); @@ -254,26 +270,26 @@ final class Photos extends VKAPIRequestHandler 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->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"); } - if(empty($title)) { + if (empty($title)) { $this->fail(25, "Title is empty"); } - if($album->isCreatedBySystem()) { + if ($album->isCreatedBySystem()) { $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"); } @@ -285,50 +301,55 @@ final class Photos extends VKAPIRequestHandler 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(); $res = []; - if(empty($album_ids)) { - if($owner_id > 0) { - $user = (new UsersRepo)->get($owner_id); + if (empty($album_ids)) { + if ($owner_id > 0) { + $user = (new UsersRepo())->get($owner_id); $res = [ - "count" => (new Albums)->getUserAlbumsCount($user), - "items" => [] + "count" => (new Albums())->getUserAlbumsCount($user), + "items" => [], ]; - if(!$user || $user->isDeleted()) + if (!$user || $user->isDeleted()) { $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."); + } - $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) { - 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); } - } - - else { - $club = (new Clubs)->get($owner_id * -1); + } else { + $club = (new Clubs())->get($owner_id * -1); $res = [ - "count" => (new Albums)->getClubAlbumsCount($club), - "items" => [] + "count" => (new Albums())->getClubAlbumsCount($club), + "items" => [], ]; - if(!$club) + if (!$club) { $this->fail(2, "Invalid club"); - - $albums = array_slice(iterator_to_array((new Albums)->getClubAlbums($club, 1, $count + $offset)), $offset); + } - foreach($albums as $album) { - if(!$need_system && $album->isCreatedBySystem()) continue; + $albums = array_slice(iterator_to_array((new Albums())->getClubAlbums($club, 1, $count + $offset)), $offset); + + foreach ($albums as $album) { + if (!$need_system && $album->isCreatedBySystem()) { + continue; + } $res["items"][] = $album->toVkApiStruct($this->getUser(), $need_covers, $photo_sizes); } } @@ -338,16 +359,17 @@ final class Photos extends VKAPIRequestHandler $res = [ "count" => sizeof($albums), - "items" => [] + "items" => [], ]; - foreach($albums as $album) - { + foreach ($albums as $album) { $id = explode("_", $album); - - $album = (new Albums)->getAlbumByOwnerAndId((int)$id[0], (int)$id[1]); - if($album && !$album->isDeleted()) { - if(!$need_system && $album->isCreatedBySystem()) continue; + + $album = (new Albums())->getAlbumByOwnerAndId((int) $id[0], (int) $id[1]); + if ($album && !$album->isDeleted()) { + if (!$need_system && $album->isCreatedBySystem()) { + continue; + } $res["items"][] = $album->toVkApiStruct($this->getUser(), $need_covers, $photo_sizes); } } @@ -356,50 +378,55 @@ final class Photos extends VKAPIRequestHandler 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(); - 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"); - - 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) { - $cl = (new Clubs)->get($group_id); - if(!$cl) { + 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) { + $cl = (new Clubs())->get($group_id); + if (!$cl) { $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(); $phts = explode(",", $photos); $res = []; - foreach($phts as $phota) { + foreach ($phts as $phota) { $ph = explode("_", $phota); - $photo = (new PhotosRepo)->getByOwnerAndVID((int)$ph[0], (int)$ph[1]); - - if(!$photo || $photo->isDeleted()) - $this->fail(21, "Invalid photo"); + $photo = (new PhotosRepo())->getByOwnerAndVID((int) $ph[0], (int) $ph[1]); - if(!$photo->canBeViewedBy($this->getUser())) + if (!$photo || $photo->isDeleted()) { + $this->fail(21, "Invalid photo"); + } + + if (!$photo->canBeViewedBy($this->getUser())) { $this->fail(15, "Access denied"); + } $res[] = $photo->toVkApiStruct($photo_sizes, $extended); } @@ -407,26 +434,30 @@ final class Photos extends VKAPIRequestHandler 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(); $res = []; - if(empty($photo_ids)) { - $album = (new Albums)->getAlbumByOwnerAndId($owner_id, $album_id); + if (empty($photo_ids)) { + $album = (new Albums())->getAlbumByOwnerAndId($owner_id, $album_id); - if(!$album || $album->isDeleted()) + if (!$album || $album->isDeleted()) { $this->fail(21, "Invalid album"); - - if(!$album->canBeViewedBy($this->getUser())) + } + + if (!$album->canBeViewedBy($this->getUser())) { $this->fail(15, "Access denied"); - + } + $photos = array_slice(iterator_to_array($album->getPhotos(1, $count + $offset)), $offset); $res["count"] = $album->size(); - foreach($photos as $photo) { - if(!$photo || $photo->isDeleted()) continue; + foreach ($photos as $photo) { + if (!$photo || $photo->isDeleted()) { + continue; + } $res["items"][] = $photo->toVkApiStruct($photo_sizes, $extended); } @@ -435,14 +466,14 @@ final class Photos extends VKAPIRequestHandler $res = [ "count" => sizeof($photos), - "items" => [] + "items" => [], ]; - foreach($photos as $photo) { + foreach ($photos as $photo) { $id = explode("_", $photo); - - $phot = (new PhotosRepo)->getByOwnerAndVID((int)$id[0], (int)$id[1]); - if($phot && !$phot->isDeleted() && $phot->canBeViewedBy($this->getUser())) { + + $phot = (new PhotosRepo())->getByOwnerAndVID((int) $id[0], (int) $id[1]); + if ($phot && !$phot->isDeleted() && $phot->canBeViewedBy($this->getUser())) { $res["items"][] = $phot->toVkApiStruct($photo_sizes, $extended); } } @@ -451,38 +482,42 @@ final class Photos extends VKAPIRequestHandler return $res; } - function deleteAlbum(int $album_id, int $group_id = 0) + public function deleteAlbum(int $album_id, int $group_id = 0) { $this->requireUser(); $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"); + } - if($album->isDeleted()) + if ($album->isDeleted()) { $this->fail(22, "Album already deleted"); + } $album->delete(); 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->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"); + } - if($photo->isDeleted()) + if ($photo->isDeleted()) { $this->fail(21, "Photo is deleted"); + } - if(!empty($caption)) { + if (!empty($caption)) { $photo->setDescription($caption); $photo->save(); } @@ -490,41 +525,46 @@ final class Photos extends VKAPIRequestHandler 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->willExecuteWriteAction(); - if(empty($photos)) { - $photo = (new PhotosRepo)->getByOwnerAndVID($owner_id, $photo_id); + if (empty($photos)) { + $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"); + } - if(!$photo) + if (!$photo) { $this->fail(21, "Invalid photo"); + } - if($photo->isDeleted()) + if ($photo->isDeleted()) { $this->fail(21, "Photo is already deleted"); + } $photo->delete(); } else { $photozs = explode(',', $photos); - foreach($photozs as $photo) - { + foreach ($photozs as $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"); + } - if(!$phot) + if (!$phot) { $this->fail(21, "Invalid photo"); - - if($phot->isDeleted()) + } + + if ($phot->isDeleted()) { $this->fail(21, "Photo already deleted"); + } $phot->delete(); } @@ -533,45 +573,50 @@ final class Photos extends VKAPIRequestHandler 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"); } - function deleteComment(int $comment_id, int $owner_id = 0) + public function deleteComment(int $comment_id, int $owner_id = 0) { $this->requireUser(); $this->willExecuteWriteAction(); - $comment = (new CommentsRepo)->get($comment_id); - if(!$comment) + $comment = (new CommentsRepo())->get($comment_id); + if (!$comment) { $this->fail(21, "Invalid comment"); + } - if(!$comment->canBeModifiedBy($this->getUser())) + if (!$comment->canBeModifiedBy($this->getUser())) { $this->fail(21, "Access denied"); + } $comment->delete(); 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->willExecuteWriteAction(); - if(empty($message) && empty($attachments)) + if (empty($message) && empty($attachments)) { $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"); + } - if(!$photo->canBeViewedBy($this->getUser())) + if (!$photo->canBeViewedBy($this->getUser())) { $this->fail(15, "Access to photo denied"); + } - $comment = new Comment; + $comment = new Comment(); $comment->setOwner($this->getUser()->getId()); $comment->setModel(get_class($photo)); $comment->setTarget($photo->getId()); @@ -579,43 +624,49 @@ final class Photos extends VKAPIRequestHandler $comment->setCreated(time()); $comment->save(); - if(!empty($attachments)) { + if (!empty($attachments)) { $attachmentsArr = explode(",", $attachments); - if(sizeof($attachmentsArr) > 10) + if (sizeof($attachmentsArr) > 10) { $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"; - elseif(str_contains($attac, "video")) + } elseif (str_contains($attac, "video")) { $attachmentType = "video"; - else + } else { $this->fail(205, "Unknown attachment type"); + } $attachment = str_replace($attachmentType, "", $attac); - $attachmentOwner = (int)explode("_", $attachment)[0]; - $attachmentId = (int)end(explode("_", $attachment)); + $attachmentOwner = (int) explode("_", $attachment)[0]; + $attachmentId = (int) end(explode("_", $attachment)); - $attacc = NULL; + $attacc = null; - if($attachmentType == "photo") { - $attacc = (new PhotosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId); - if(!$attacc || $attacc->isDeleted()) + if ($attachmentType == "photo") { + $attacc = (new PhotosRepo())->getByOwnerAndVID($attachmentOwner, $attachmentId); + if (!$attacc || $attacc->isDeleted()) { $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"); - + } + $comment->attach($attacc); - } elseif($attachmentType == "video") { - $attacc = (new VideosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId); - if(!$attacc || $attacc->isDeleted()) + } elseif ($attachmentType == "video") { + $attacc = (new VideosRepo())->getByOwnerAndVID($attachmentOwner, $attachmentId); + if (!$attacc || $attacc->isDeleted()) { $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"); + } $comment->attach($attacc); } @@ -625,56 +676,63 @@ final class Photos extends VKAPIRequestHandler 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(); - if($owner_id < 0) + if ($owner_id < 0) { $this->fail(4, "This method doesn't works with clubs"); + } - $user = (new UsersRepo)->get($owner_id); - if(!$user) + $user = (new UsersRepo())->get($owner_id); + if (!$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 = [ - "count" => (new PhotosRepo)->getUserPhotosCount($user), + "count" => (new PhotosRepo())->getUserPhotosCount($user), "items" => [], ]; - foreach($photos as $photo) { - if(!$photo || $photo->isDeleted()) continue; + foreach ($photos as $photo) { + if (!$photo || $photo->isDeleted()) { + continue; + } $res["items"][] = $photo->toVkApiStruct($photo_sizes, $extended); } 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(); - $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); - if(!$photo || $photo->isDeleted()) + if (!$photo || $photo->isDeleted()) { $this->fail(4, "Invalid photo"); + } - if(!$photo->canBeViewedBy($this->getUser())) + if (!$photo->canBeViewedBy($this->getUser())) { $this->fail(21, "Access denied"); + } $res = [ "count" => sizeof($comms), - "items" => [] + "items" => [], ]; - foreach($comms as $comment) { + foreach ($comms as $comment) { $res["items"][] = $comment->toVkApiStruct($this->getUser(), $need_likes, $extended); - if($extended) { - if($comment->getOwner() instanceof \openvk\Web\Models\Entities\User) { + if ($extended) { + if ($comment->getOwner() instanceof \openvk\Web\Models\Entities\User) { $res["profiles"][] = $comment->getOwner()->toVkApiStruct(); } } diff --git a/VKAPI/Handlers/Polls.php b/VKAPI/Handlers/Polls.php index c84f8283..8c1842c9 100755 --- a/VKAPI/Handlers/Polls.php +++ b/VKAPI/Handlers/Polls.php @@ -1,170 +1,184 @@ -get($poll_id); - - if (!$poll) - $this->fail(100, "One of the parameters specified was missing or invalid: poll_id is incorrect"); - - $users = array(); - $answers = array(); - foreach($poll->getResults()->options as $answer) { - $answers[] = (object)[ - "id" => $answer->id, - "rate" => $answer->pct, - "text" => $answer->name, - "votes" => $answer->votes - ]; - } - - $userVote = array(); - foreach($poll->getUserVote($this->getUser()) as $vote) - $userVote[] = $vote[0]; - - $response = [ - "multiple" => $poll->isMultipleChoice(), - "end_date" => $poll->endsAt() == NULL ? 0 : $poll->endsAt()->timestamp(), - "closed" => $poll->hasEnded(), - "is_board" => false, - "can_edit" => false, - "can_vote" => $poll->canVote($this->getUser()), - "can_report" => false, - "can_share" => true, - "created" => 0, - "id" => $poll->getId(), - "owner_id" => $poll->getOwner()->getId(), - "question" => $poll->getTitle(), - "votes" => $poll->getVoterCount(), - "disable_unvote" => $poll->isRevotable(), - "anonymous" => $poll->isAnonymous(), - "answer_ids" => $userVote, - "answers" => $answers, - "author_id" => $poll->getOwner()->getId(), - ]; - - if ($extended) { - $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 - */ - } - - return (object) $response; - } - - function addVote(int $poll_id, string $answers_ids) - { - $this->requireUser(); - $this->willExecuteWriteAction(); - - $poll = (new PollsRepo)->get($poll_id); - - if(!$poll) - $this->fail(251, "Invalid poll id"); - - try { - $poll->vote($this->getUser(), explode(",", $answers_ids)); - return 1; - } catch(AlreadyVotedException $ex) { - return 0; - } catch(PollLockedException $ex) { - return 0; - } catch(InvalidOptionException $ex) { - $this->fail(8, "бдсм вибратор купить в киеве"); - } - } - - function deleteVote(int $poll_id) - { - $this->requireUser(); - $this->willExecuteWriteAction(); - - $poll = (new PollsRepo)->get($poll_id); - - if(!$poll) - $this->fail(251, "Invalid poll id"); - - try { - $poll->revokeVote($this->getUser()); - return 1; - } catch(PollLockedException $ex) { - $this->fail(15, "Access denied: Poll is locked or isn't revotable"); - } catch(InvalidOptionException $ex) { - $this->fail(8, "how.to. ook.bacon.in.microwova."); - } - } - - function getVoters(int $poll_id, int $answer_ids, int $offset = 0, int $count = 6) - { - $this->requireUser(); - - $poll = (new PollsRepo)->get($poll_id); - - if(!$poll) - $this->fail(251, "Invalid poll"); - - if($poll->isAnonymous()) - $this->fail(251, "Access denied: poll is anonymous."); - - $voters = array_slice($poll->getVoters($answer_ids, 1, $offset + $count), $offset); - $res = (object)[ - "answer_id" => $answer_ids, - "users" => [] - ]; - - foreach($voters as $voter) - $res->users[] = $voter->toVkApiStruct(); - - return $res; - } - - function create(string $question, string $add_answers, bool $disable_unvote = false, bool $is_anonymous = false, bool $is_multiple = false, int $end_date = 0) - { - $this->requireUser(); - $this->willExecuteWriteAction(); - - $options = json_decode($add_answers); - - if(!$options || empty($options)) - $this->fail(62, "Invalid options"); - - if(sizeof($options) > ovkGetQuirk("polls.max-opts")) - $this->fail(51, "Too many options"); - - $poll = new Poll; - $poll->setOwner($this->getUser()); - $poll->setTitle($question); - $poll->setMultipleChoice($is_multiple); - $poll->setAnonymity($is_anonymous); - $poll->setRevotability(!$disable_unvote); - $poll->setOptions($options); - - if($end_date > time()) { - if($end_date > time() + (DAY * 365)) - $this->fail(89, "End date is too big"); - - $poll->setEndDate($end_date); - } - - $poll->save(); - - return $this->getById($poll->getId()); - } - - function edit() - { - #todo - return 1; - } -} +get($poll_id); + + if (!$poll) { + $this->fail(100, "One of the parameters specified was missing or invalid: poll_id is incorrect"); + } + + $users = []; + $answers = []; + foreach ($poll->getResults()->options as $answer) { + $answers[] = (object) [ + "id" => $answer->id, + "rate" => $answer->pct, + "text" => $answer->name, + "votes" => $answer->votes, + ]; + } + + $userVote = []; + foreach ($poll->getUserVote($this->getUser()) as $vote) { + $userVote[] = $vote[0]; + } + + $response = [ + "multiple" => $poll->isMultipleChoice(), + "end_date" => $poll->endsAt() == null ? 0 : $poll->endsAt()->timestamp(), + "closed" => $poll->hasEnded(), + "is_board" => false, + "can_edit" => false, + "can_vote" => $poll->canVote($this->getUser()), + "can_report" => false, + "can_share" => true, + "created" => 0, + "id" => $poll->getId(), + "owner_id" => $poll->getOwner()->getId(), + "question" => $poll->getTitle(), + "votes" => $poll->getVoterCount(), + "disable_unvote" => $poll->isRevotable(), + "anonymous" => $poll->isAnonymous(), + "answer_ids" => $userVote, + "answers" => $answers, + "author_id" => $poll->getOwner()->getId(), + ]; + + if ($extended) { + $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 + */ + } + + return (object) $response; + } + + public function addVote(int $poll_id, string $answers_ids) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $poll = (new PollsRepo())->get($poll_id); + + if (!$poll) { + $this->fail(251, "Invalid poll id"); + } + + try { + $poll->vote($this->getUser(), explode(",", $answers_ids)); + return 1; + } catch (AlreadyVotedException $ex) { + return 0; + } catch (PollLockedException $ex) { + return 0; + } catch (InvalidOptionException $ex) { + $this->fail(8, "бдсм вибратор купить в киеве"); + } + } + + public function deleteVote(int $poll_id) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $poll = (new PollsRepo())->get($poll_id); + + if (!$poll) { + $this->fail(251, "Invalid poll id"); + } + + try { + $poll->revokeVote($this->getUser()); + return 1; + } catch (PollLockedException $ex) { + $this->fail(15, "Access denied: Poll is locked or isn't revotable"); + } catch (InvalidOptionException $ex) { + $this->fail(8, "how.to. ook.bacon.in.microwova."); + } + } + + public function getVoters(int $poll_id, int $answer_ids, int $offset = 0, int $count = 6) + { + $this->requireUser(); + + $poll = (new PollsRepo())->get($poll_id); + + if (!$poll) { + $this->fail(251, "Invalid poll"); + } + + if ($poll->isAnonymous()) { + $this->fail(251, "Access denied: poll is anonymous."); + } + + $voters = array_slice($poll->getVoters($answer_ids, 1, $offset + $count), $offset); + $res = (object) [ + "answer_id" => $answer_ids, + "users" => [], + ]; + + foreach ($voters as $voter) { + $res->users[] = $voter->toVkApiStruct(); + } + + return $res; + } + + public function create(string $question, string $add_answers, bool $disable_unvote = false, bool $is_anonymous = false, bool $is_multiple = false, int $end_date = 0) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + $options = json_decode($add_answers); + + if (!$options || empty($options)) { + $this->fail(62, "Invalid options"); + } + + if (sizeof($options) > ovkGetQuirk("polls.max-opts")) { + $this->fail(51, "Too many options"); + } + + $poll = new Poll(); + $poll->setOwner($this->getUser()); + $poll->setTitle($question); + $poll->setMultipleChoice($is_multiple); + $poll->setAnonymity($is_anonymous); + $poll->setRevotability(!$disable_unvote); + $poll->setOptions($options); + + if ($end_date > time()) { + if ($end_date > time() + (DAY * 365)) { + $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; + } +} diff --git a/VKAPI/Handlers/Reports.php b/VKAPI/Handlers/Reports.php index 3a5a1d19..13198dcc 100644 --- a/VKAPI/Handlers/Reports.php +++ b/VKAPI/Handlers/Reports.php @@ -1,42 +1,46 @@ -requireUser(); $this->willExecuteWriteAction(); $allowed_types = ["post", "photo", "video", "group", "comment", "note", "app", "user", "audio"]; - 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)); + 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)); } - if($owner_id <= 0) { + if ($owner_id <= 0) { $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"); } - if($type == "user" && $owner_id == $this->getUser()->getId()) { + if ($type == "user" && $owner_id == $this->getUser()->getId()) { return 1; } - if($this->getUser()->isBannedInSupport()) { + if ($this->getUser()->isBannedInSupport()) { 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; } try { - $report = new Report; + $report = new Report(); $report->setUser_id($this->getUser()->getId()); $report->setTarget_id($owner_id); $report->setType($type); @@ -44,7 +48,7 @@ final class Reports extends VKAPIRequestHandler $report->setCreated(time()); $report->save(); - } catch(\Throwable $e) { + } catch (\Throwable $e) { $this->fail(-1, "Unknown error failed"); } diff --git a/VKAPI/Handlers/Status.php b/VKAPI/Handlers/Status.php index 5234a7fc..e8c7b17a 100644 --- a/VKAPI/Handlers/Status.php +++ b/VKAPI/Handlers/Status.php @@ -1,27 +1,33 @@ -requireUser(); - - if($user_id == 0 && $group_id == 0) + + if ($user_id == 0 && $group_id == 0) { $user_id = $this->getUser()->getId(); + } - if($group_id > 0) + if ($group_id > 0) { $this->fail(501, "Group statuses are not implemented"); - else { - $user = (new UsersRepo)->get($user_id); + } else { + $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"); + } $audioStatus = $user->getCurrentAudioStatus(); - if($audioStatus) { + if ($audioStatus) { return [ "status" => $user->getStatus(), "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->willExecuteWriteAction(); - if($group_id > 0) { + if ($group_id > 0) { $this->fail(501, "Group statuses are not implemented"); } else { $this->getUser()->setStatus($text); $this->getUser()->save(); - + return 1; } } diff --git a/VKAPI/Handlers/Users.php b/VKAPI/Handlers/Users.php index c47acb8e..e3d27073 100644 --- a/VKAPI/Handlers/Users.php +++ b/VKAPI/Handlers/Users.php @@ -1,5 +1,9 @@ -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); - $response = array(); + $response = []; $ic = sizeof($usrs); - if(sizeof($usrs) > $count) - $ic = $count; + if (sizeof($usrs) > $count) { + $ic = $count; + } $usrs = array_slice($usrs, $offset * $count); - for($i=0; $i < $ic; $i++) { - if($usrs[$i] != 0) { - $usr = $users->get((int) $usrs[$i]); - if(is_null($usr) || $usr->isDeleted()) { - $response[$i] = (object)[ - "id" => (int) $usrs[$i], - "first_name" => "DELETED", - "last_name" => "", - "deactivated" => "deleted" - ]; - } else if($usr->isBanned()) { - $response[$i] = (object)[ - "id" => $usr->getId(), - "first_name" => $usr->getFirstName(true), - "last_name" => $usr->getLastName(true), - "deactivated" => "banned", - "ban_reason" => $usr->getBanReason() - ]; - } else if($usrs[$i] == NULL) { + for ($i = 0; $i < $ic; $i++) { + if ($usrs[$i] != 0) { + $usr = $users->get((int) $usrs[$i]); + if (is_null($usr) || $usr->isDeleted()) { + $response[$i] = (object) [ + "id" => (int) $usrs[$i], + "first_name" => "DELETED", + "last_name" => "", + "deactivated" => "deleted", + ]; + } elseif ($usr->isBanned()) { + $response[$i] = (object) [ + "id" => $usr->getId(), + "first_name" => $usr->getFirstName(true), + "last_name" => $usr->getLastName(true), + "deactivated" => "banned", + "ban_reason" => $usr->getBanReason(), + ]; + } elseif ($usrs[$i] == null) { - } else { - $response[$i] = (object)[ - "id" => $usr->getId(), - "first_name" => $usr->getFirstName(true), - "last_name" => $usr->getLastName(true), - "is_closed" => $usr->isClosed(), - "can_access_closed" => (bool)$usr->canBeViewedBy($this->getUser()), - ]; + } else { + $response[$i] = (object) [ + "id" => $usr->getId(), + "first_name" => $usr->getFirstName(true), + "last_name" => $usr->getLastName(true), + "is_closed" => $usr->isClosed(), + "can_access_closed" => (bool) $usr->canBeViewedBy($this->getUser()), + ]; - $flds = explode(',', $fields); - $canView = $usr->canBeViewedBy($this->getUser()); - foreach($flds as $field) { - switch($field) { - case "verified": - $response[$i]->verified = intval($usr->isVerified()); - break; - case "sex": - $response[$i]->sex = $usr->isFemale() ? 1 : ($usr->isNeutral() ? 0 : 2); - break; - case "has_photo": - $response[$i]->has_photo = is_null($usr->getAvatarPhoto()) ? 0 : 1; - break; - case "photo_max_orig": - $response[$i]->photo_max_orig = $usr->getAvatarURL(); - break; - case "photo_max": - $response[$i]->photo_max = $usr->getAvatarURL("original"); - break; - case "photo_50": - $response[$i]->photo_50 = $usr->getAvatarURL(); - break; - case "photo_100": - $response[$i]->photo_100 = $usr->getAvatarURL("tiny"); - break; - case "photo_200": - $response[$i]->photo_200 = $usr->getAvatarURL("normal"); - break; - case "photo_200_orig": # вообще не ебу к чему эта строка ну пусть будет кек - $response[$i]->photo_200_orig = $usr->getAvatarURL("normal"); - break; - case "photo_400_orig": - $response[$i]->photo_400_orig = $usr->getAvatarURL("normal"); - break; - - # Она хочет быть выебанной видя матан - # Покайфу когда ты Виет а вокруг лишь дискриминант + $flds = explode(',', $fields); + $canView = $usr->canBeViewedBy($this->getUser()); + foreach ($flds as $field) { + switch ($field) { + case "verified": + $response[$i]->verified = intval($usr->isVerified()); + break; + case "sex": + $response[$i]->sex = $usr->isFemale() ? 1 : ($usr->isNeutral() ? 0 : 2); + break; + case "has_photo": + $response[$i]->has_photo = is_null($usr->getAvatarPhoto()) ? 0 : 1; + break; + case "photo_max_orig": + $response[$i]->photo_max_orig = $usr->getAvatarURL(); + break; + case "photo_max": + $response[$i]->photo_max = $usr->getAvatarURL("original"); + break; + case "photo_50": + $response[$i]->photo_50 = $usr->getAvatarURL(); + break; + case "photo_100": + $response[$i]->photo_100 = $usr->getAvatarURL("tiny"); + break; + case "photo_200": + $response[$i]->photo_200 = $usr->getAvatarURL("normal"); + break; + case "photo_200_orig": # вообще не ебу к чему эта строка ну пусть будет кек + $response[$i]->photo_200_orig = $usr->getAvatarURL("normal"); + break; + case "photo_400_orig": + $response[$i]->photo_400_orig = $usr->getAvatarURL("normal"); + 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; - 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; + $audioStatus = $usr->getCurrentAudioStatus(); - case 'android': - $platform = 4; - break; + if ($audioStatus) { + $response[$i]->status_audio = $audioStatus->toVkApiStruct(); + } - case NULL: - $platform = 7; - break; - - default: - $platform = 1; - break; - } + break; + 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; - $response[$i]->last_seen = (object) [ - "platform" => $platform, - "time" => $usr->getOnline()->timestamp() - ]; - } - case "music": - if(!$canView) { - break; - } + case 'android': + $platform = 4; + break; - $response[$i]->music = $usr->getFavoriteMusic(); - break; - case "movies": - if(!$canView) { - break; - } + case null: + $platform = 7; + break; - $response[$i]->movies = $usr->getFavoriteFilms(); - break; - case "tv": - if(!$canView) { - break; - } + default: + $platform = 1; + break; + } - $response[$i]->tv = $usr->getFavoriteShows(); - break; - case "books": - if(!$canView) { - break; - } + $response[$i]->last_seen = (object) [ + "platform" => $platform, + "time" => $usr->getOnline()->timestamp(), + ]; + } + // no break + case "music": + if (!$canView) { + break; + } - $response[$i]->books = $usr->getFavoriteBooks(); - break; - case "city": - if(!$canView) { - break; - } + $response[$i]->music = $usr->getFavoriteMusic(); + break; + case "movies": + if (!$canView) { + break; + } - $response[$i]->city = $usr->getCity(); - break; - case "interests": - if(!$canView) { - break; - } + $response[$i]->movies = $usr->getFavoriteFilms(); + break; + case "tv": + if (!$canView) { + break; + } - $response[$i]->interests = $usr->getInterests(); - break; - case "quotes": - if(!$canView) { - break; - } + $response[$i]->tv = $usr->getFavoriteShows(); + break; + case "books": + if (!$canView) { + break; + } - $response[$i]->quotes = $usr->getFavoriteQuote(); - break; - case "games": - if(!$canView) { - break; - } + $response[$i]->books = $usr->getFavoriteBooks(); + break; + case "city": + if (!$canView) { + break; + } - $response[$i]->games = $usr->getFavoriteGames(); - break; - case "email": - if(!$canView) { - break; - } + $response[$i]->city = $usr->getCity(); + break; + case "interests": + if (!$canView) { + break; + } - $response[$i]->email = $usr->getContactEmail(); - break; - case "telegram": - if(!$canView) { - break; - } + $response[$i]->interests = $usr->getInterests(); + break; + case "quotes": + if (!$canView) { + break; + } - $response[$i]->telegram = $usr->getTelegram(); - break; - case "about": - if(!$canView) { - break; - } - - $response[$i]->about = $usr->getDescription(); - break; - case "rating": - if(!$canView) { - break; - } + $response[$i]->quotes = $usr->getFavoriteQuote(); + break; + case "games": + 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; + $response[$i]->games = $usr->getFavoriteGames(); + break; + case "email": + if (!$canView) { + break; + } + + $response[$i]->email = $usr->getContactEmail(); + break; + case "telegram": + if (!$canView) { + break; + } + + $response[$i]->telegram = $usr->getTelegram(); + break; + case "about": + if (!$canView) { + 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": $response[$i]->guid = $usr->getChandlerGUID(); break; - case 'background': - $backgrounds = $usr->getBackDropPictureURLs(); - $response[$i]->background = $backgrounds; - break; - case 'reg_date': - if(!$canView) { - 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; - } + case 'background': + $backgrounds = $usr->getBackDropPictureURLs(); + $response[$i]->background = $backgrounds; + break; + case 'reg_date': + if (!$canView) { + break; + } - $response[$i]->blacklisted_by_me = (int)$usr->isBlacklistedBy($this->getUser()); - break; - case 'blacklisted': - if(!$authuser) { - continue; - } - - $response[$i]->blacklisted = (int)$this->getUser()->isBlacklistedBy($usr); - break; - case "custom_fields": - if(sizeof($usrs) > 1) - 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; + } - $c_fields = \openvk\Web\Models\Entities\UserInfoEntities\AdditionalField::getByOwner($usr->getId()); - $append_array = []; - foreach($c_fields as $c_field) - $append_array[] = $c_field->toVkApiStruct(); + $response[$i]->blacklisted_by_me = (int) $usr->isBlacklistedBy($this->getUser()); + break; + case 'blacklisted': + if (!$authuser) { + continue; + } - $response[$i]->custom_fields = $append_array; - break; - } - } + $response[$i]->blacklisted = (int) $this->getUser()->isBlacklistedBy($usr); + break; + case "custom_fields": + if (sizeof($usrs) > 1) { + break; + } - if($usr->getOnline()->timestamp() + 300 > time()) - $response[$i]->online = 1; - else - $response[$i]->online = 0; - } - } + $c_fields = \openvk\Web\Models\Entities\UserInfoEntities\AdditionalField::getByOwner($usr->getId()); + $append_array = []; + foreach ($c_fields as $c_field) { + $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; } - 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++; $followers = []; - $users = new UsersRepo; + $users = new UsersRepo(); $this->requireUser(); - + $user = $users->get($user_id); - - if(!$user || $user->isDeleted()) + + if (!$user || $user->isDeleted()) { $this->fail(14, "Invalid user"); + } - if(!$user->canBeViewedBy($this->getUser())) + if (!$user->canBeViewedBy($this->getUser())) { $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(); + } $response = $followers; - if(!is_null($fields)) - $response = $this->get(implode(',', $followers), $fields, 0, $count); + if (!is_null($fields)) { + $response = $this->get(implode(',', $followers), $fields, 0, $count); + } return (object) [ "count" => $users->get($user_id)->getFollowersCount(), - "items" => $response + "items" => $response, ]; } - function search(string $q, - string $fields = "", - int $offset = 0, - int $count = 100, - string $city = "", - string $hometown = "", - int $sex = 3, - int $status = 0, # marital_status - bool $online = false, - # non standart params: - int $sort = 0, - int $polit_views = 0, - string $fav_music = "", - string $fav_films = "", - string $fav_shows = "", - string $fav_books = "" - ) - { - if($count > 100) { + public function search( + string $q, + string $fields = "", + int $offset = 0, + int $count = 100, + string $city = "", + string $hometown = "", + int $sex = 3, + int $status = 0, # marital_status + bool $online = false, + # non standart params: + int $sort = 0, + int $polit_views = 0, + string $fav_music = "", + string $fav_films = "", + string $fav_shows = "", + string $fav_books = "" + ) { + if ($count > 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_params = [ - "ignore_private" => true, - ]; + $output_params = [ + "ignore_private" => true, + ]; - switch($sort) { - default: + switch ($sort) { + default: case 0: $output_sort = ['type' => 'id', 'invert' => false]; break; @@ -386,50 +404,62 @@ final class Users extends VKAPIRequestHandler $output_sort = ['type' => 'id', 'invert' => true]; break; case 4: - $output_sort = ['type' => 'rating', 'invert' => false]; + $output_sort = ['type' => 'rating', 'invert' => false]; break; } - if(!empty($city)) + if (!empty($city)) { $output_params['city'] = $city; + } - if(!empty($hometown)) + if (!empty($hometown)) { $output_params['hometown'] = $hometown; + } - if($sex != 3) - $output_params['gender'] = $sex; + if ($sex != 3) { + $output_params['gender'] = $sex; + } - if($status != 0) + if ($status != 0) { $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; + } - if(!empty($fav_music)) + if (!empty($fav_music)) { $output_params['fav_music'] = $fav_music; + } - if(!empty($fav_films)) + if (!empty($fav_films)) { $output_params['fav_films'] = $fav_films; + } - if(!empty($fav_shows)) + if (!empty($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; + } $array = []; $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(); + } - if(!$array || sizeof($array) < 1) { + if (!$array || sizeof($array) < 1) { return (object) [ "count" => 0, "items" => [], @@ -438,29 +468,31 @@ final class Users extends VKAPIRequestHandler return (object) [ "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 = "") - { - $this->requireUser(); - $this->willExecuteWriteAction(); + public function report(int $user_id, string $type = "spam", string $comment = "") + { + $this->requireUser(); + $this->willExecuteWriteAction(); - if($user_id == $this->getUser()->getId()) - $this->fail(12, "Can't report yourself."); + if ($user_id == $this->getUser()->getId()) { + $this->fail(12, "Can't report yourself."); + } - if(sizeof(iterator_to_array((new Reports)->getDuplicates("user", $user_id, NULL, $this->getUser()->getId()))) > 0) - return 1; + if (sizeof(iterator_to_array((new Reports())->getDuplicates("user", $user_id, null, $this->getUser()->getId()))) > 0) { + return 1; + } - $report = new Report; - $report->setUser_id($this->getUser()->getId()); - $report->setTarget_id($user_id); - $report->setType("user"); - $report->setReason($comment); - $report->setCreated(time()); - $report->save(); + $report = new Report(); + $report->setUser_id($this->getUser()->getId()); + $report->setTarget_id($user_id); + $report->setType("user"); + $report->setReason($comment); + $report->setCreated(time()); + $report->save(); - return 1; - } + return 1; + } } diff --git a/VKAPI/Handlers/Utils.php b/VKAPI/Handlers/Utils.php index a1c4f3b5..000ebe5e 100644 --- a/VKAPI/Handlers/Utils.php +++ b/VKAPI/Handlers/Utils.php @@ -1,55 +1,62 @@ -getMatchingRoute("/$screen_name")[0]->presenter !== "UnknownTextRouteStrategy") { - if(substr($screen_name, 0, strlen("id")) === "id") { - return (object) [ - "object_id" => (int) substr($screen_name, strlen("id")), - "type" => "user" - ]; - } else if(substr($screen_name, 0, strlen("club")) === "club") { - return (object) [ - "object_id" => (int) substr($screen_name, strlen("club")), - "type" => "group" - ]; - } else $this->fail(104, "Not found"); - } else { - $user = (new Users)->getByShortURL($screen_name); - if($user) { - return (object) [ - "object_id" => $user->getId(), - "type" => "user" - ]; - } - - $club = (new Clubs)->getByShortURL($screen_name); - if($club) { - return (object) [ - "object_id" => $club->getId(), - "type" => "group" - ]; - } - - $this->fail(104, "Not found"); - } - } - - function resolveGuid(string $guid): object - { - $user = (new Users)->getByChandlerUserId($guid); - if (is_null($user)) - $this->fail(104, "Not found"); - - return $user->toVkApiStruct($this->getUser()); - } -} +getMatchingRoute("/$screen_name")[0]->presenter !== "UnknownTextRouteStrategy") { + if (substr($screen_name, 0, strlen("id")) === "id") { + return (object) [ + "object_id" => (int) substr($screen_name, strlen("id")), + "type" => "user", + ]; + } elseif (substr($screen_name, 0, strlen("club")) === "club") { + return (object) [ + "object_id" => (int) substr($screen_name, strlen("club")), + "type" => "group", + ]; + } else { + $this->fail(104, "Not found"); + } + } else { + $user = (new Users())->getByShortURL($screen_name); + if ($user) { + return (object) [ + "object_id" => $user->getId(), + "type" => "user", + ]; + } + + $club = (new Clubs())->getByShortURL($screen_name); + if ($club) { + return (object) [ + "object_id" => $club->getId(), + "type" => "group", + ]; + } + + $this->fail(104, "Not found"); + } + } + + 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()); + } +} diff --git a/VKAPI/Handlers/VKAPIRequestHandler.php b/VKAPI/Handlers/VKAPIRequestHandler.php index 4953dbe1..b67c4797 100644 --- a/VKAPI/Handlers/VKAPIRequestHandler.php +++ b/VKAPI/Handlers/VKAPIRequestHandler.php @@ -1,5 +1,9 @@ -user = $user; $this->platform = $platform; } - + protected function fail(int $code, string $message): void { throw new APIErrorException($message, $code); } - + protected function getUser(): ?User { return $this->user; } - + protected function getPlatform(): ?string { return $this->platform ?? ""; } - + protected function userAuthorized(): bool { return !is_null($this->getUser()); } - + protected function requireUser(): void { - if(!$this->userAuthorized()) + if (!$this->userAuthorized()) { $this->fail(5, "User authorization failed: no access_token passed."); + } } - + protected function willExecuteWriteAction(): void { - $ip = (new IPs)->get(CONNECTING_IP); + $ip = (new IPs())->get(CONNECTING_IP); $res = $ip->rateLimit(); - - 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_RESET || $res === IP::RL_CANEXEC)) { + 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->fail(18, "User account has been suspended due to repeated violation of API rate limits."); } - + $this->fail(29, "You have been rate limited."); } } diff --git a/VKAPI/Handlers/Video.php b/VKAPI/Handlers/Video.php index 3a14f048..f8cecf05 100755 --- a/VKAPI/Handlers/Video.php +++ b/VKAPI/Handlers/Video.php @@ -1,5 +1,9 @@ -requireUser(); - if(!empty($videos)) { + if (!empty($videos)) { $vids = explode(',', $videos); $profiles = []; $groups = []; - foreach($vids as $vid) { + foreach ($vids as $vid) { $id = explode("_", $vid); $items = []; - - $video = (new VideosRepo)->getByOwnerAndVID(intval($id[0]), intval($id[1])); - if($video && !$video->isDeleted()) { + + $video = (new VideosRepo())->getByOwnerAndVID(intval($id[0]), intval($id[1])); + if ($video && !$video->isDeleted()) { $out_video = $video->getApiStructure($this->getUser())->video; $items[] = $out_video; - if($out_video['owner_id']) { - if($out_video['owner_id'] > 0) + if ($out_video['owner_id']) { + if ($out_video['owner_id'] > 0) { $profiles[] = $out_video['owner_id']; - else + } else { $groups[] = abs($out_video['owner_id']); + } } } } - if($extended == 1) { + if ($extended == 1) { $profiles = array_unique($profiles); $groups = array_unique($groups); - + $profilesFormatted = []; $groupsFormatted = []; - - foreach($profiles as $prof) { - $profile = (new UsersRepo)->get($prof); + + foreach ($profiles as $prof) { + $profile = (new UsersRepo())->get($prof); $profilesFormatted[] = $profile->toVkApiStruct($this->getUser(), $fields); } - - foreach($groups as $gr) { - $group = (new ClubsRepo)->get($gr); + + foreach ($groups as $gr) { + $group = (new ClubsRepo())->get($gr); $groupsFormatted[] = $group->toVkApiStruct($this->getUser(), $fields); } - + return (object) [ "count" => sizeof($items), "items" => $items, @@ -60,57 +65,61 @@ final class Video extends VKAPIRequestHandler "groups" => $groupsFormatted, ]; } - + return (object) [ "count" => count($items), - "items" => $items + "items" => $items, ]; } else { - if ($owner_id > 0) - $user = (new UsersRepo)->get($owner_id); - else + if ($owner_id > 0) { + $user = (new UsersRepo())->get($owner_id); + } else { $this->fail(1, "Not implemented"); - - if(!$user || $user->isDeleted()) + } + + if (!$user || $user->isDeleted()) { $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."); + } + + $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 = []; $profiles = []; $groups = []; - foreach($videos as $video) { + foreach ($videos as $video) { $video = $video->getApiStructure($this->getUser())->video; $items[] = $video; - if($video['owner_id']) { - if($video['owner_id'] > 0) + if ($video['owner_id']) { + if ($video['owner_id'] > 0) { $profiles[] = $video['owner_id']; - else + } else { $groups[] = abs($video['owner_id']); + } } } - if($extended == 1) { + if ($extended == 1) { $profiles = array_unique($profiles); $groups = array_unique($groups); - + $profilesFormatted = []; $groupsFormatted = []; - - foreach($profiles as $prof) { - $profile = (new UsersRepo)->get($prof); + + foreach ($profiles as $prof) { + $profile = (new UsersRepo())->get($prof); $profilesFormatted[] = $profile->toVkApiStruct($this->getUser(), $fields); } - - foreach($groups as $gr) { - $group = (new ClubsRepo)->get($gr); + + foreach ($groups as $gr) { + $group = (new ClubsRepo())->get($gr); $groupsFormatted[] = $group->toVkApiStruct($this->getUser(), $fields); } - + return (object) [ "count" => $videosCount, "items" => $items, @@ -118,54 +127,55 @@ final class Video extends VKAPIRequestHandler "groups" => $groupsFormatted, ]; } - + return (object) [ "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(); $params = []; $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)); $count = $videos->size(); $return_items = []; $profiles = []; $groups = []; - foreach($items as $item) { + foreach ($items as $item) { $return_item = $item->getApiStructure($this->getUser()); $return_item = $return_item->video; $return_items[] = $return_item; - if($return_item['owner_id']) { - if($return_item['owner_id'] > 0) + if ($return_item['owner_id']) { + if ($return_item['owner_id'] > 0) { $profiles[] = $return_item['owner_id']; - else + } else { $groups[] = abs($return_item['owner_id']); + } } } - if($extended) { + if ($extended) { $profiles = array_unique($profiles); $groups = array_unique($groups); $profilesFormatted = []; $groupsFormatted = []; - foreach($profiles as $prof) { - $profile = (new UsersRepo)->get($prof); + foreach ($profiles as $prof) { + $profile = (new UsersRepo())->get($prof); $profilesFormatted[] = $profile->toVkApiStruct($this->getUser(), $fields); } - foreach($groups as $gr) { - $group = (new ClubsRepo)->get($gr); + foreach ($groups as $gr) { + $group = (new ClubsRepo())->get($gr); $groupsFormatted[] = $group->toVkApiStruct($this->getUser(), $fields); } diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index 125d62a6..3bc56b93 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -1,5 +1,9 @@ -requireUser(); - $posts = new PostsRepo; + $posts = new PostsRepo(); $items = []; $profiles = []; $groups = []; $cnt = 0; - if ($owner_id > 0) - $wallOnwer = (new UsersRepo)->get($owner_id); - else - $wallOnwer = (new ClubsRepo)->get($owner_id * -1); + if ($owner_id > 0) { + $wallOnwer = (new UsersRepo())->get($owner_id); + } else { + $wallOnwer = (new ClubsRepo())->get($owner_id * -1); + } - if ($owner_id > 0) - if(!$wallOnwer || $wallOnwer->isDeleted()) + if ($owner_id > 0) { + if (!$wallOnwer || $wallOnwer->isDeleted()) { $this->fail(18, "User was deleted or banned"); + } + } - if(!$wallOnwer->canBeViewedBy($this->getUser())) - $this->fail(15, "Access denied"); - else - if(!$wallOnwer) - $this->fail(15, "Access denied: wall is disabled"); // Don't search for logic here pls + if (!$wallOnwer->canBeViewedBy($this->getUser())) { + $this->fail(15, "Access denied"); + } elseif (!$wallOnwer) { + $this->fail(15, "Access denied: wall is disabled"); + } // Don't search for logic here pls $iteratorv; - switch($filter) { + switch ($filter) { case "all": $iteratorv = $posts->getPostsFromUsersWall($owner_id, 1, $count, $offset); $cnt = $posts->getPostCountOnUserWall($owner_id); @@ -60,16 +67,17 @@ final class Wall extends VKAPIRequestHandler case "others": $iteratorv = $posts->getOthersPostsFromWall($owner_id, 1, $count, $offset); $cnt = $posts->getOthersCountOnUserWall($owner_id); - break; + break; case "postponed": $this->fail(42, "Postponed posts are not implemented."); break; case "suggests": - if($owner_id < 0) { - if($wallOnwer->getWallType() != 2) + if ($owner_id < 0) { + if ($wallOnwer->getWallType() != 2) { $this->fail(125, "Group's wall type is open or closed"); + } - if($wallOnwer->canBeModifiedBy($this->getUser())) { + if ($wallOnwer->canBeModifiedBy($this->getUser())) { $iteratorv = $posts->getSuggestedPosts($owner_id * -1, 1, $count, $offset); $cnt = $posts->getSuggestedPostsCount($owner_id * -1); } else { @@ -88,57 +96,60 @@ final class Wall extends VKAPIRequestHandler $iteratorv = iterator_to_array($iteratorv); - foreach($iteratorv as $post) { + foreach ($iteratorv as $post) { $from_id = get_class($post->getOwner()) == "openvk\Web\Models\Entities\Club" ? $post->getOwner()->getId() * (-1) : $post->getOwner()->getId(); $attachments = []; $repost = []; - foreach($post->getChildren() as $attachment) { - if($attachment instanceof \openvk\Web\Models\Entities\Photo) { - if($attachment->isDeleted()) + foreach ($post->getChildren() as $attachment) { + if ($attachment instanceof \openvk\Web\Models\Entities\Photo) { + if ($attachment->isDeleted()) { continue; + } $attachments[] = $this->getApiPhoto($attachment); - } else if($attachment instanceof \openvk\Web\Models\Entities\Poll) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Poll) { $attachments[] = $this->getApiPoll($attachment, $this->getUser()); - } else if ($attachment instanceof \openvk\Web\Models\Entities\Video) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Video) { $attachments[] = $attachment->getApiStructure($this->getUser()); - } else if ($attachment instanceof \openvk\Web\Models\Entities\Note) { - if(VKAPI_DECL_VER === '4.100') { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Note) { + if (VKAPI_DECL_VER === '4.100') { $attachments[] = $attachment->toVkApiStruct(); } else { $attachments[] = [ 'type' => 'note', - 'note' => $attachment->toVkApiStruct() + 'note' => $attachment->toVkApiStruct(), ]; } - } else if ($attachment instanceof \openvk\Web\Models\Entities\Audio) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Audio) { $attachments[] = [ "type" => "audio", "audio" => $attachment->toVkApiStruct($this->getUser()), ]; - } else if ($attachment instanceof \openvk\Web\Models\Entities\Document) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Document) { $attachments[] = [ "type" => "doc", "doc" => $attachment->toVkApiStruct($this->getUser()), ]; - } else if ($attachment instanceof \openvk\Web\Models\Entities\Post) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Post) { $repostAttachments = []; - foreach($attachment->getChildren() as $repostAttachment) { - if($repostAttachment instanceof \openvk\Web\Models\Entities\Photo) { - if($repostAttachment->isDeleted()) + foreach ($attachment->getChildren() as $repostAttachment) { + if ($repostAttachment instanceof \openvk\Web\Models\Entities\Photo) { + if ($repostAttachment->isDeleted()) { continue; + } $repostAttachments[] = $this->getApiPhoto($repostAttachment); /* Рекурсии, сука! Заказывали? */ } } - if ($attachment->isPostedOnBehalfOfGroup()) + if ($attachment->isPostedOnBehalfOfGroup()) { $groups[] = $attachment->getOwner()->getId(); - else + } else { $profiles[] = $attachment->getOwner()->getId(); + } $repost[] = [ "id" => $attachment->getVirtualId(), @@ -151,17 +162,19 @@ final class Wall extends VKAPIRequestHandler "post_source" => $attachment->getPostSourceInfo(), ]; - if ($attachment->getTargetWall() > 0) + if ($attachment->getTargetWall() > 0) { $profiles[] = $attachment->getTargetWall(); - else + } else { $groups[] = abs($attachment->getTargetWall()); - if($post->isSigned()) - $profiles[] = $attachment->getOwner()->getId(); + } + if ($post->isSigned()) { + $profiles[] = $attachment->getOwner()->getId(); + } } } - $signerId = NULL; - if($post->isSigned()) { + $signerId = null; + if ($post->isSigned()) { $actualAuthor = $post->getOwner(false); $signerId = $actualAuthor->getId(); } @@ -169,7 +182,7 @@ final class Wall extends VKAPIRequestHandler # TODO "can_pin", "copy_history" и прочее не должны возвращаться, если равны null или false # Ну и ещё всё надо перенести в toVkApiStruct, а то слишком много дублированного кода - $post_temp_obj = (object)[ + $post_temp_obj = (object) [ "id" => $post->getVirtualId(), "from_id" => $from_id, "owner_id" => $post->getTargetWall(), @@ -186,54 +199,60 @@ final class Wall extends VKAPIRequestHandler "is_explicit" => $post->isExplicit(), "attachments" => $attachments, "post_source" => $post->getPostSourceInfo(), - "comments" => (object)[ + "comments" => (object) [ "count" => $post->getCommentsCount(), - "can_post" => 1 + "can_post" => 1, ], - "likes" => (object)[ + "likes" => (object) [ "count" => $post->getLikesCount(), "user_likes" => (int) $post->hasLikeFrom($this->getUser()), "can_like" => 1, "can_publish" => 1, ], - "reposts" => (object)[ + "reposts" => (object) [ "count" => $post->getRepostCount(), - "user_reposted" => 0 - ] + "user_reposted" => 0, + ], ]; - if($post->hasSource()) + if ($post->hasSource()) { $post_temp_obj->copyright = $post->getVkApiCopyright(); + } - if($signerId) + if ($signerId) { $post_temp_obj->signer_id = $signerId; + } - if($post->isDeactivationMessage()) + if ($post->isDeactivationMessage()) { $post_temp_obj->final_post = 1; + } - if($post->getGeo()) + if ($post->getGeo()) { $post_temp_obj->geo = $post->getVkApiGeo(); + } $items[] = $post_temp_obj; - if ($from_id > 0) + if ($from_id > 0) { $profiles[] = $from_id; - else + } else { $groups[] = $from_id * -1; + } - if($post->isSigned()) - $profiles[] = $post->getOwner(false)->getId(); + if ($post->isSigned()) { + $profiles[] = $post->getOwner(false)->getId(); + } - $attachments = NULL; # free attachments so it will not clone everythingg + $attachments = null; # free attachments so it will not clone everythingg } - if($rss == 1) { + if ($rss == 1) { $channel = new \Bhaktaraz\RSSGenerator\Channel(); $channel->title($wallOnwer->getCanonicalName() . " — " . OPENVK_ROOT_CONF['openvk']['appearance']['name']) ->description('Wall of ' . $wallOnwer->getCanonicalName()) ->url(ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/wall" . $wallOnwer->getRealId()); - foreach($iteratorv as $item) { + foreach ($iteratorv as $item) { $output = $item->toRss(); $output->appendTo($channel); } @@ -241,33 +260,33 @@ final class Wall extends VKAPIRequestHandler return $channel; } - if($extended == 1) { + if ($extended == 1) { $profiles = array_unique($profiles); $groups = array_unique($groups); $profilesFormatted = []; $groupsFormatted = []; - foreach($profiles as $prof) { - $user = (new UsersRepo)->get($prof); - $profilesFormatted[] = (object)[ + foreach ($profiles as $prof) { + $user = (new UsersRepo())->get($prof); + $profilesFormatted[] = (object) [ "first_name" => $user->getFirstName(), "id" => $user->getId(), "last_name" => $user->getLastName(), - "can_access_closed" => (bool)$user->canBeViewedBy($this->getUser()), + "can_access_closed" => (bool) $user->canBeViewedBy($this->getUser()), "is_closed" => $user->isClosed(), "sex" => $user->isFemale() ? 1 : ($user->isNeutral() ? 0 : 2), "screen_name" => $user->getShortCode(), "photo_50" => $user->getAvatarUrl(), "photo_100" => $user->getAvatarUrl(), "online" => $user->isOnline(), - "verified" => $user->isVerified() + "verified" => $user->isVerified(), ]; } - foreach($groups as $g) { - $group = (new ClubsRepo)->get($g); - $groupsFormatted[] = (object)[ + foreach ($groups as $g) { + $group = (new ClubsRepo())->get($g); + $groupsFormatted[] = (object) [ "id" => $group->getId(), "name" => $group->getName(), "screen_name" => $group->getShortCode(), @@ -276,7 +295,7 @@ final class Wall extends VKAPIRequestHandler "photo_50" => $group->getAvatarUrl(), "photo_100" => $group->getAvatarUrl(), "photo_200" => $group->getAvatarUrl(), - "verified" => $group->isVerified() + "verified" => $group->isVerified(), ]; } @@ -284,18 +303,19 @@ final class Wall extends VKAPIRequestHandler "count" => $cnt, "items" => $items, "profiles" => $profilesFormatted, - "groups" => $groupsFormatted + "groups" => $groupsFormatted, ]; - } else + } else { return (object) [ "count" => $cnt, - "items" => $items + "items" => $items, ]; + } } - function getById(string $posts, int $extended = 0, string $fields = "", User $user = NULL) + public function getById(string $posts, int $extended = 0, string $fields = "", User $user = null) { - if($user == NULL) { + if ($user == null) { $this->requireUser(); $user = $this->getUser(); # костыли костыли крылышки } @@ -306,60 +326,63 @@ final class Wall extends VKAPIRequestHandler $psts = explode(',', $posts); - foreach($psts as $pst) { + foreach ($psts as $pst) { $id = explode("_", $pst); - $post = (new PostsRepo)->getPostById(intval($id[0]), intval($id[1]), true); + $post = (new PostsRepo())->getPostById(intval($id[0]), intval($id[1]), true); - if($post && !$post->isDeleted()) { - if(!$post->canBeViewedBy($this->getUser())) + if ($post && !$post->isDeleted()) { + if (!$post->canBeViewedBy($this->getUser())) { continue; + } - if($post->getSuggestionType() != 0 && !$post->canBeEditedBy($this->getUser())) { + if ($post->getSuggestionType() != 0 && !$post->canBeEditedBy($this->getUser())) { continue; } $from_id = get_class($post->getOwner()) == "openvk\Web\Models\Entities\Club" ? $post->getOwner()->getId() * (-1) : $post->getOwner()->getId(); $attachments = []; $repost = []; // чел высрал семь сигарет 😳 помянем 🕯 - foreach($post->getChildren() as $attachment) { - if($attachment instanceof \openvk\Web\Models\Entities\Photo) { + foreach ($post->getChildren() as $attachment) { + if ($attachment instanceof \openvk\Web\Models\Entities\Photo) { $attachments[] = $this->getApiPhoto($attachment); - } else if($attachment instanceof \openvk\Web\Models\Entities\Poll) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Poll) { $attachments[] = $this->getApiPoll($attachment, $user); - } else if ($attachment instanceof \openvk\Web\Models\Entities\Video) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Video) { $attachments[] = $attachment->getApiStructure($this->getUser()); - } else if ($attachment instanceof \openvk\Web\Models\Entities\Note) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Note) { $attachments[] = [ 'type' => 'note', - 'note' => $attachment->toVkApiStruct() + 'note' => $attachment->toVkApiStruct(), ]; - } else if ($attachment instanceof \openvk\Web\Models\Entities\Audio) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Audio) { $attachments[] = [ "type" => "audio", - "audio" => $attachment->toVkApiStruct($this->getUser()) + "audio" => $attachment->toVkApiStruct($this->getUser()), ]; - } else if ($attachment instanceof \openvk\Web\Models\Entities\Document) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Document) { $attachments[] = [ "type" => "doc", "doc" => $attachment->toVkApiStruct($this->getUser()), ]; - } else if ($attachment instanceof \openvk\Web\Models\Entities\Post) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Post) { $repostAttachments = []; - foreach($attachment->getChildren() as $repostAttachment) { - if($repostAttachment instanceof \openvk\Web\Models\Entities\Photo) { - if($attachment->isDeleted()) + foreach ($attachment->getChildren() as $repostAttachment) { + if ($repostAttachment instanceof \openvk\Web\Models\Entities\Photo) { + if ($attachment->isDeleted()) { continue; + } $repostAttachments[] = $this->getApiPhoto($repostAttachment); /* Рекурсии, сука! Заказывали? */ } } - if ($attachment->isPostedOnBehalfOfGroup()) + if ($attachment->isPostedOnBehalfOfGroup()) { $groups[] = $attachment->getOwner()->getId(); - else + } else { $profiles[] = $attachment->getOwner()->getId(); + } $repost[] = [ "id" => $attachment->getVirtualId(), @@ -372,21 +395,23 @@ final class Wall extends VKAPIRequestHandler "post_source" => $attachment->getPostSourceInfo(), ]; - if ($attachment->getTargetWall() > 0) + if ($attachment->getTargetWall() > 0) { $profiles[] = $attachment->getTargetWall(); - else + } else { $groups[] = abs($attachment->getTargetWall()); - if($post->isSigned()) - $profiles[] = $attachment->getOwner()->getId(); + } + if ($post->isSigned()) { + $profiles[] = $attachment->getOwner()->getId(); + } } } - if($post->isSigned()) { + if ($post->isSigned()) { $actualAuthor = $post->getOwner(false); $signerId = $actualAuthor->getId(); } - $post_temp_obj = (object)[ + $post_temp_obj = (object) [ "id" => $post->getVirtualId(), "from_id" => $from_id, "owner_id" => $post->getTargetWall(), @@ -403,85 +428,91 @@ final class Wall extends VKAPIRequestHandler "is_explicit" => $post->isExplicit(), "post_source" => $post->getPostSourceInfo(), "attachments" => $attachments, - "comments" => (object)[ + "comments" => (object) [ "count" => $post->getCommentsCount(), - "can_post" => 1 + "can_post" => 1, ], - "likes" => (object)[ + "likes" => (object) [ "count" => $post->getLikesCount(), "user_likes" => (int) $post->hasLikeFrom($user), "can_like" => 1, "can_publish" => 1, ], - "reposts" => (object)[ + "reposts" => (object) [ "count" => $post->getRepostCount(), - "user_reposted" => 0 - ] + "user_reposted" => 0, + ], ]; - if($post->hasSource()) + if ($post->hasSource()) { $post_temp_obj->copyright = $post->getVkApiCopyright(); + } - if($signerId) + if ($signerId) { $post_temp_obj->signer_id = $signerId; + } - if($post->isDeactivationMessage()) + if ($post->isDeactivationMessage()) { $post_temp_obj->final_post = 1; + } - if($post->getGeo()) + if ($post->getGeo()) { $post_temp_obj->geo = $post->getVkApiGeo(); + } $items[] = $post_temp_obj; - if ($from_id > 0) + if ($from_id > 0) { $profiles[] = $from_id; - else + } else { $groups[] = $from_id * -1; + } - if($post->isSigned()) - $profiles[] = $post->getOwner(false)->getId(); + if ($post->isSigned()) { + $profiles[] = $post->getOwner(false)->getId(); + } - $attachments = NULL; # free attachments so it will not clone everything - $repost = NULL; # same + $attachments = null; # free attachments so it will not clone everything + $repost = null; # same } } - if($extended == 1) { + if ($extended == 1) { $profiles = array_unique($profiles); $groups = array_unique($groups); $profilesFormatted = []; $groupsFormatted = []; - foreach($profiles as $prof) { - $user = (new UsersRepo)->get($prof); - if($user) { - $profilesFormatted[] = (object)[ + foreach ($profiles as $prof) { + $user = (new UsersRepo())->get($prof); + if ($user) { + $profilesFormatted[] = (object) [ "first_name" => $user->getFirstName(), "id" => $user->getId(), "last_name" => $user->getLastName(), - "can_access_closed" => (bool)$user->canBeViewedBy($this->getUser()), + "can_access_closed" => (bool) $user->canBeViewedBy($this->getUser()), "is_closed" => $user->isClosed(), "sex" => $user->isFemale() ? 1 : 2, "screen_name" => $user->getShortCode(), "photo_50" => $user->getAvatarUrl(), "photo_100" => $user->getAvatarUrl(), "online" => $user->isOnline(), - "verified" => $user->isVerified() + "verified" => $user->isVerified(), ]; } else { - $profilesFormatted[] = (object)[ + $profilesFormatted[] = (object) [ "id" => (int) $prof, "first_name" => "DELETED", "last_name" => "", - "deactivated" => "deleted" + "deactivated" => "deleted", ]; } } - foreach($groups as $g) { - $group = (new ClubsRepo)->get($g); - $groupsFormatted[] = (object)[ + foreach ($groups as $g) { + $group = (new ClubsRepo())->get($g); + $groupsFormatted[] = (object) [ "id" => $group->getId(), "name" => $group->getName(), "screen_name" => $group->getShortCode(), @@ -490,118 +521,141 @@ final class Wall extends VKAPIRequestHandler "photo_50" => $group->getAvatarUrl(), "photo_100" => $group->getAvatarUrl(), "photo_200" => $group->getAvatarUrl(), - "verified" => $group->isVerified() + "verified" => $group->isVerified(), ]; } return (object) [ - "items" => (array)$items, - "profiles" => (array)$profilesFormatted, - "groups" => (array)$groupsFormatted + "items" => (array) $items, + "profiles" => (array) $profilesFormatted, + "groups" => (array) $groupsFormatted, ]; - } else + } else { return (object) [ - "items" => (array)$items + "items" => (array) $items, ]; + } } - function post(string $owner_id, string $message = "", string $copyright = "", int $from_group = 0, int $signed = 0, string $attachments = "", int $post_id = 0, - float $lat = NULL, - float $long = NULL, - string $place_name = '' - ): object - { + public function post( + string $owner_id, + string $message = "", + string $copyright = "", + int $from_group = 0, + int $signed = 0, + string $attachments = "", + int $post_id = 0, + float $lat = null, + float $long = null, + string $place_name = '' + ): object { $this->requireUser(); $this->willExecuteWriteAction(); $owner_id = intval($owner_id); - $wallOwner = ($owner_id > 0 ? (new UsersRepo)->get($owner_id) : (new ClubsRepo)->get($owner_id * -1)) + $wallOwner = ($owner_id > 0 ? (new UsersRepo())->get($owner_id) : (new ClubsRepo())->get($owner_id * -1)) ?? $this->fail(18, "User was deleted or banned"); - if($owner_id > 0) + if ($owner_id > 0) { $canPost = $wallOwner->getPrivacyPermission("wall.write", $this->getUser()) && $wallOwner->canBeViewedBy($this->getUser()); - else if($owner_id < 0) - if($wallOwner->canBeModifiedBy($this->getUser())) + } elseif ($owner_id < 0) { + if ($wallOwner->canBeModifiedBy($this->getUser())) { $canPost = true; - else + } else { $canPost = $wallOwner->canPost(); - else + } + } else { $canPost = false; + } - if($canPost == false) $this->fail(15, "Access denied"); + if ($canPost == false) { + $this->fail(15, "Access denied"); + } - if($post_id > 0) { - if($owner_id > 0) + if ($post_id > 0) { + if ($owner_id > 0) { $this->fail(62, "Suggested posts available only at groups"); + } - $post = (new PostsRepo)->getPostById($owner_id, $post_id, true); + $post = (new PostsRepo())->getPostById($owner_id, $post_id, true); - if(!$post || $post->isDeleted()) + if (!$post || $post->isDeleted()) { $this->fail(32, "Invald post"); + } - if($post->getSuggestionType() == 0) + if ($post->getSuggestionType() == 0) { $this->fail(20, "Post is not suggested"); + } - if($post->getSuggestionType() == 2) + if ($post->getSuggestionType() == 2) { $this->fail(16, "Post is declined"); + } - if(!$post->canBePinnedBy($this->getUser())) + if (!$post->canBePinnedBy($this->getUser())) { $this->fail(51, "Access denied"); + } $author = $post->getOwner(); $flags = 0; $flags |= 0b10000000; - if($signed == 1) + if ($signed == 1) { $flags |= 0b01000000; + } $post->setSuggested(0); $post->setCreated(time()); $post->setFlags($flags); - if(!empty($message) && iconv_strlen($message) > 0) + if (!empty($message) && iconv_strlen($message) > 0) { $post->setContent($message); + } $post->save(); - if($author->getId() != $this->getUser()->getId()) + if ($author->getId() != $this->getUser()->getId()) { (new PostAcceptedNotification($author, $post, $post->getWallOwner()))->emit(); + } - return (object)["post_id" => $post->getVirtualId()]; + return (object) ["post_id" => $post->getVirtualId()]; } $anon = OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["enable"]; - if($wallOwner instanceof Club && $from_group == 1 && $signed != 1 && $anon) { + if ($wallOwner instanceof Club && $from_group == 1 && $signed != 1 && $anon) { $manager = $wallOwner->getManager($this->getUser()); - if($manager) + if ($manager) { $anon = $manager->isHidden(); - elseif($this->getUser()->getId() === $wallOwner->getOwner()->getId()) + } elseif ($this->getUser()->getId() === $wallOwner->getOwner()->getId()) { $anon = $wallOwner->isOwnerHidden(); + } } else { $anon = false; } $flags = 0; - if($from_group == 1 && $wallOwner instanceof Club && $wallOwner->canBeModifiedBy($this->getUser())) + if ($from_group == 1 && $wallOwner instanceof Club && $wallOwner->canBeModifiedBy($this->getUser())) { $flags |= 0b10000000; - if($signed == 1) + } + if ($signed == 1) { $flags |= 0b01000000; + } $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'poll', 'audio', 'doc']); $final_attachments = []; $should_be_suggested = $owner_id < 0 && !$wallOwner->canBeModifiedBy($this->getUser()) && $wallOwner->getWallType() == 2; - foreach($parsed_attachments as $attachment) { - if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && + foreach ($parsed_attachments as $attachment) { + if ($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && !(method_exists($attachment, 'getVoters') && $attachment->getOwner()->getId() != $this->getUser()->getId())) { $final_attachments[] = $attachment; } } - if((empty($message) && (empty($attachments) || sizeof($final_attachments) < 1))) + if ((empty($message) && (empty($attachments) || sizeof($final_attachments) < 1))) { $this->fail(100, "Required parameter 'message' missing."); + } try { - $post = new Post; + $post = new Post(); $post->setOwner($this->getUser()->getId()); $post->setWall($owner_id); $post->setCreated(time()); @@ -609,12 +663,13 @@ final class Wall extends VKAPIRequestHandler $post->setFlags($flags); $post->setApi_Source_Name($this->getPlatform()); - if(!is_null($copyright) && !empty($copyright)) { + if (!is_null($copyright) && !empty($copyright)) { try { $post->setSource($copyright); - } catch(\Throwable) {} + } catch (\Throwable) { + } } - + /*$info = file_get_contents("https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=jsonv2", false, stream_context_create([ 'http' => [ 'method' => 'GET', @@ -631,8 +686,8 @@ final class Wall extends VKAPIRequestHandler $geo["name"] = $info["name"] ?? $info["display_name"]; } }*/ - if($lat && $long) { - if(($lat > 90 || $lat < -90) || ($long > 180 || $long < -180)) { + if ($lat && $long) { + if (($lat > 90 || $lat < -90) || ($long > 180 || $long < -180)) { $this->fail(-785, 'Invalid geo info'); } @@ -641,9 +696,9 @@ final class Wall extends VKAPIRequestHandler $res = [ 'lat' => $latitude, - 'lng' => $longitude + 'lng' => $longitude, ]; - if($place_name && mb_strlen($place_name) > 0) { + if ($place_name && mb_strlen($place_name) > 0) { $res['name'] = $place_name; } else { $res['name'] = 'Geopoint'; @@ -654,97 +709,108 @@ final class Wall extends VKAPIRequestHandler $post->setGeo_Lon($longitude); } - if($should_be_suggested) + if ($should_be_suggested) { $post->setSuggested(1); + } $post->save(); - } catch(\LogicException $ex) { + } catch (\LogicException $ex) { $this->fail(100, "One of the parameters specified was missing or invalid"); } - foreach($final_attachments as $attachment) { + foreach ($final_attachments as $attachment) { $post->attach($attachment); } - if($wall > 0 && $wall !== $this->user->identity->getId()) + if ($wall > 0 && $wall !== $this->user->identity->getId()) { (new WallPostNotification($wallOwner, $post, $this->user->identity))->emit(); + } - return (object)["post_id" => $post->getVirtualId()]; + return (object) ["post_id" => $post->getVirtualId()]; } - function repost(string $object, string $message = "", string $attachments = "", int $group_id = 0, int $as_group = 0, int $signed = 0) { + public function repost(string $object, string $message = "", string $attachments = "", int $group_id = 0, int $as_group = 0, int $signed = 0) + { $this->requireUser(); $this->willExecuteWriteAction(); $postArray; - if(preg_match('/(wall|video|photo)((?:-?)[0-9]+)_([0-9]+)/', $object, $postArray) == 0) + if (preg_match('/(wall|video|photo)((?:-?)[0-9]+)_([0-9]+)/', $object, $postArray) == 0) { $this->fail(100, "One of the parameters specified was missing or invalid: object is incorrect"); + } $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio', 'doc']); $final_attachments = []; - foreach($parsed_attachments as $attachment) { - if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && + foreach ($parsed_attachments as $attachment) { + if ($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && !(method_exists($attachment, 'getVoters') && $attachment->getOwner()->getId() != $this->getUser()->getId())) { $final_attachments[] = $attachment; } } - $repost_entity = NULL; + $repost_entity = null; $repost_type = $postArray[1]; - switch($repost_type) { + switch ($repost_type) { default: case 'wall': - $repost_entity = (new PostsRepo)->getPostById((int) $postArray[2], (int) $postArray[3]); + $repost_entity = (new PostsRepo())->getPostById((int) $postArray[2], (int) $postArray[3]); break; case 'photo': - $repost_entity = (new PhotosRepo)->getByOwnerAndVID((int) $postArray[2], (int) $postArray[3]); + $repost_entity = (new PhotosRepo())->getByOwnerAndVID((int) $postArray[2], (int) $postArray[3]); break; case 'video': - $repost_entity = (new VideosRepo)->getByOwnerAndVID((int) $postArray[2], (int) $postArray[3]); + $repost_entity = (new VideosRepo())->getByOwnerAndVID((int) $postArray[2], (int) $postArray[3]); break; } - if(!$repost_entity || $repost_entity->isDeleted() || !$repost_entity->canBeViewedBy($this->getUser())) $this->fail(100, "One of the parameters specified was missing or invalid"); + if (!$repost_entity || $repost_entity->isDeleted() || !$repost_entity->canBeViewedBy($this->getUser())) { + $this->fail(100, "One of the parameters specified was missing or invalid"); + } - $nPost = new Post; + $nPost = new Post(); $nPost->setOwner($this->user->getId()); - - if($group_id > 0) { - $club = (new ClubsRepo)->get($group_id); - if(!$club) + + if ($group_id > 0) { + $club = (new ClubsRepo())->get($group_id); + if (!$club) { $this->fail(42, "Invalid group"); - - if(!$club->canBeModifiedBy($this->user)) + } + + if (!$club->canBeModifiedBy($this->user)) { $this->fail(16, "Access to group denied"); - + } + $nPost->setWall($club->getRealId()); $flags = 0; - if($as_group === 1 || $signed === 1) + if ($as_group === 1 || $signed === 1) { $flags |= 0b10000000; + } - if($signed === 1) + if ($signed === 1) { $flags |= 0b01000000; + } $nPost->setFlags($flags); } else { $nPost->setWall($this->user->getId()); } - + $nPost->setContent($message); $nPost->setApi_Source_Name($this->getPlatform()); $nPost->save(); $nPost->attach($repost_entity); - foreach($parsed_attachments as $attachment) { + foreach ($parsed_attachments as $attachment) { $nPost->attach($attachment); } - if($repost_type == 'wall' && $repost_entity->getOwner(false)->getId() !== $this->user->getId() && !($repost_entity->getOwner() instanceof Club)) + if ($repost_type == 'wall' && $repost_entity->getOwner(false)->getId() !== $this->user->getId() && !($repost_entity->getOwner() instanceof Club)) { (new RepostNotification($repost_entity->getOwner(false), $repost_entity, $this->user))->emit(); + } $repost_count = 1; - if($repost_type == 'wall') { + if ($repost_type == 'wall') { $repost_count = $repost_entity->getRepostCount(); } @@ -753,44 +819,49 @@ final class Wall extends VKAPIRequestHandler "post_id" => $nPost->getVirtualId(), "pretty_id" => $nPost->getPrettyId(), "reposts_count" => $repost_count, - "likes_count" => $repost_entity->getLikesCount() + "likes_count" => $repost_entity->getLikesCount(), ]; } - function getComments(int $owner_id, int $post_id, bool $need_likes = true, int $offset = 0, int $count = 10, string $fields = "sex,screen_name,photo_50,photo_100,online_info,online", string $sort = "asc", bool $extended = false) { + public function getComments(int $owner_id, int $post_id, bool $need_likes = true, int $offset = 0, int $count = 10, string $fields = "sex,screen_name,photo_50,photo_100,online_info,online", string $sort = "asc", bool $extended = false) + { $this->requireUser(); - $post = (new PostsRepo)->getPostById($owner_id, $post_id); - if(!$post || $post->isDeleted()) $this->fail(100, "One of the parameters specified was missing or invalid"); - - if(!$post->canBeViewedBy($this->getUser())) - $this->fail(15, "Access denied"); + $post = (new PostsRepo())->getPostById($owner_id, $post_id); + if (!$post || $post->isDeleted()) { + $this->fail(100, "One of the parameters specified was missing or invalid"); + } - $comments = (new CommentsRepo)->getCommentsByTarget($post, $offset+1, $count, $sort == "desc" ? "DESC" : "ASC"); + if (!$post->canBeViewedBy($this->getUser())) { + $this->fail(15, "Access denied"); + } + + $comments = (new CommentsRepo())->getCommentsByTarget($post, $offset + 1, $count, $sort == "desc" ? "DESC" : "ASC"); $items = []; $profiles = []; - foreach($comments as $comment) { + foreach ($comments as $comment) { $owner = $comment->getOwner(); $oid = $owner->getId(); - if($owner instanceof Club) + if ($owner instanceof Club) { $oid *= -1; + } $attachments = []; - foreach($comment->getChildren() as $attachment) { - if($attachment instanceof \openvk\Web\Models\Entities\Photo) { + foreach ($comment->getChildren() as $attachment) { + if ($attachment instanceof \openvk\Web\Models\Entities\Photo) { $attachments[] = $this->getApiPhoto($attachment); - } elseif($attachment instanceof \openvk\Web\Models\Entities\Note) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Note) { $attachments[] = $attachment->toVkApiStruct(); - } elseif($attachment instanceof \openvk\Web\Models\Entities\Audio) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Audio) { $attachments[] = [ - "type" => "audio", + "type" => "audio", "audio" => $attachment->toVkApiStruct($this->getUser()), ]; - } else if ($attachment instanceof \openvk\Web\Models\Entities\Document) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Document) { $attachments[] = [ "type" => "doc", "doc" => $attachment->toVkApiStruct($this->getUser()), @@ -813,76 +884,82 @@ final class Wall extends VKAPIRequestHandler "can_post" => false, "show_reply_button" => true, "groups_can_post" => false, - ] + ], ]; - if($comment->isFromPostAuthor($post)) + if ($comment->isFromPostAuthor($post)) { $item['is_from_post_author'] = true; + } - if($need_likes == true) + if ($need_likes == true) { $item['likes'] = [ "can_like" => 1, "count" => $comment->getLikesCount(), "user_likes" => (int) $comment->hasLikeFrom($this->getUser()), - "can_publish" => 1 + "can_publish" => 1, ]; + } $items[] = $item; - if($extended == true) + if ($extended == true) { $profiles[] = $comment->getOwner()->getId(); + } $attachments = null; // Reset $attachments to not duplicate prikols } $response = [ - "count" => (new CommentsRepo)->getCommentsCountByTarget($post), + "count" => (new CommentsRepo())->getCommentsCountByTarget($post), "items" => $items, - "current_level_count" => (new CommentsRepo)->getCommentsCountByTarget($post), + "current_level_count" => (new CommentsRepo())->getCommentsCountByTarget($post), "can_post" => true, "show_reply_button" => true, - "groups_can_post" => false + "groups_can_post" => false, ]; - if($extended == true) { + if ($extended == true) { $profiles = array_unique($profiles); - $response['profiles'] = (!empty($profiles) ? (new Users)->get(implode(',', $profiles), $fields) : []); + $response['profiles'] = (!empty($profiles) ? (new Users())->get(implode(',', $profiles), $fields) : []); } return (object) $response; } - function getComment(int $owner_id, int $comment_id, bool $extended = false, string $fields = "sex,screen_name,photo_50,photo_100,online_info,online") { + public function getComment(int $owner_id, int $comment_id, bool $extended = false, string $fields = "sex,screen_name,photo_50,photo_100,online_info,online") + { $this->requireUser(); - $comment = (new CommentsRepo)->get($comment_id); # один хуй айди всех комментов общий - - if(!$comment || $comment->isDeleted()) + $comment = (new CommentsRepo())->get($comment_id); # один хуй айди всех комментов общий + + if (!$comment || $comment->isDeleted()) { $this->fail(100, "Invalid comment"); - - if(!$comment->canBeViewedBy($this->getUser())) + } + + if (!$comment->canBeViewedBy($this->getUser())) { $this->fail(15, "Access denied"); + } $profiles = []; $attachments = []; - foreach($comment->getChildren() as $attachment) { - if($attachment instanceof \openvk\Web\Models\Entities\Photo) { + foreach ($comment->getChildren() as $attachment) { + if ($attachment instanceof \openvk\Web\Models\Entities\Photo) { $attachments[] = $this->getApiPhoto($attachment); - } elseif($attachment instanceof \openvk\Web\Models\Entities\Video) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Video) { $attachments[] = $attachment->getApiStructure(); - } elseif($attachment instanceof \openvk\Web\Models\Entities\Note) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Note) { $attachments[] = [ 'type' => 'note', - 'note' => $attachment->toVkApiStruct() + 'note' => $attachment->toVkApiStruct(), ]; - } elseif($attachment instanceof \openvk\Web\Models\Entities\Audio) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Audio) { $attachments[] = [ "type" => "audio", "audio" => $attachment->toVkApiStruct($this->getUser()), ]; - } else if ($attachment instanceof \openvk\Web\Models\Entities\Document) { + } elseif ($attachment instanceof \openvk\Web\Models\Entities\Document) { $attachments[] = [ "type" => "doc", "doc" => $attachment->toVkApiStruct($this->getUser()), @@ -903,7 +980,7 @@ final class Wall extends VKAPIRequestHandler "can_like" => 1, "count" => $comment->getLikesCount(), "user_likes" => (int) $comment->hasLikeFrom($this->getUser()), - "can_publish" => 1 + "can_publish" => 1, ], "thread" => [ "count" => 0, @@ -911,62 +988,70 @@ final class Wall extends VKAPIRequestHandler "can_post" => false, "show_reply_button" => true, "groups_can_post" => false, - ] + ], ]; - if($comment->isFromPostAuthor()) + if ($comment->isFromPostAuthor()) { $item['is_from_post_author'] = true; + } - if($extended == true) + if ($extended == true) { $profiles[] = $comment->getOwner()->getId(); + } $response = [ "items" => [$item], "can_post" => true, "show_reply_button" => true, - "groups_can_post" => false + "groups_can_post" => false, ]; - if($extended == true) { + if ($extended == true) { $profiles = array_unique($profiles); - $response['profiles'] = (!empty($profiles) ? (new Users)->get(implode(',', $profiles), $fields) : []); + $response['profiles'] = (!empty($profiles) ? (new Users())->get(implode(',', $profiles), $fields) : []); } return $response; } - function createComment(int $owner_id, int $post_id, string $message = "", int $from_group = 0, string $attachments = "") { + public function createComment(int $owner_id, int $post_id, string $message = "", int $from_group = 0, string $attachments = "") + { $this->requireUser(); $this->willExecuteWriteAction(); - $post = (new PostsRepo)->getPostById($owner_id, $post_id); - if(!$post || $post->isDeleted()) $this->fail(100, "Invalid post"); + $post = (new PostsRepo())->getPostById($owner_id, $post_id); + if (!$post || $post->isDeleted()) { + $this->fail(100, "Invalid post"); + } - if(!$post->canBeViewedBy($this->getUser())) + if (!$post->canBeViewedBy($this->getUser())) { $this->fail(15, "Access denied"); + } - if($post->getTargetWall() < 0) - $club = (new ClubsRepo)->get(abs($post->getTargetWall())); + if ($post->getTargetWall() < 0) { + $club = (new ClubsRepo())->get(abs($post->getTargetWall())); + } $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio', 'doc']); $final_attachments = []; - foreach($parsed_attachments as $attachment) { - if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && + foreach ($parsed_attachments as $attachment) { + if ($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && !(method_exists($attachment, 'getVoters') && $attachment->getOwner()->getId() != $this->getUser()->getId())) { $final_attachments[] = $attachment; } } - if((empty($message) && (empty($attachments) || sizeof($final_attachments) < 1))) { + if ((empty($message) && (empty($attachments) || sizeof($final_attachments) < 1))) { $this->fail(100, "Required parameter 'message' missing."); } $flags = 0; - if($from_group != 0 && !is_null($club) && $club->canBeModifiedBy($this->user)) + if ($from_group != 0 && !is_null($club) && $club->canBeModifiedBy($this->user)) { $flags |= 0b10000000; + } try { - $comment = new Comment; + $comment = new Comment(); $comment->setOwner($this->user->getId()); $comment->setModel(get_class($post)); $comment->setTarget($post->getId()); @@ -978,49 +1063,57 @@ final class Wall extends VKAPIRequestHandler $this->fail(1, "ошибка про то что коммент большой слишком"); } - foreach($final_attachments as $attachment) { + foreach ($final_attachments as $attachment) { $comment->attach($attachment); } - if($post->getOwner()->getId() !== $this->user->getId()) - if(($owner = $post->getOwner()) instanceof User) + if ($post->getOwner()->getId() !== $this->user->getId()) { + if (($owner = $post->getOwner()) instanceof User) { (new CommentNotification($owner, $comment, $post, $this->user))->emit(); + } + } return (object) [ "comment_id" => $comment->getId(), - "parents_stack" => [] + "parents_stack" => [], ]; } - function deleteComment(int $comment_id) { + public function deleteComment(int $comment_id) + { $this->requireUser(); $this->willExecuteWriteAction(); - $comment = (new CommentsRepo)->get($comment_id); - if(!$comment) $this->fail(100, "One of the parameters specified was missing or invalid");; - if(!$comment->canBeDeletedBy($this->user)) + $comment = (new CommentsRepo())->get($comment_id); + if (!$comment) { + $this->fail(100, "One of the parameters specified was missing or invalid"); + }; + if (!$comment->canBeDeletedBy($this->user)) { $this->fail(7, "Access denied"); + } $comment->delete(); return 1; } - - function delete(int $owner_id, int $post_id) + + public function delete(int $owner_id, int $post_id) { $this->requireUser(); $this->willExecuteWriteAction(); - $post = (new PostsRepo)->getPostById($owner_id, $post_id, true); - if(!$post || $post->isDeleted()) + $post = (new PostsRepo())->getPostById($owner_id, $post_id, true); + if (!$post || $post->isDeleted()) { $this->fail(583, "Invalid post"); + } $wallOwner = $post->getWallOwner(); - - if($post->getTargetWall() < 0 && !$post->getWallOwner()->canBeModifiedBy($this->getUser()) && $post->getWallOwner()->getWallType() != 1 && $post->getSuggestionType() == 0) - $this->fail(12, "Access denied: you can't delete your accepted post."); - if($post->getOwnerPost() == $this->getUser()->getId() || $post->getTargetWall() == $this->getUser()->getId() || $owner_id < 0 && $wallOwner->canBeModifiedBy($this->getUser())) { + if ($post->getTargetWall() < 0 && !$post->getWallOwner()->canBeModifiedBy($this->getUser()) && $post->getWallOwner()->getWallType() != 1 && $post->getSuggestionType() == 0) { + $this->fail(12, "Access denied: you can't delete your accepted post."); + } + + if ($post->getOwnerPost() == $this->getUser()->getId() || $post->getTargetWall() == $this->getUser()->getId() || $owner_id < 0 && $wallOwner->canBeModifiedBy($this->getUser())) { $post->unwire(); $post->delete(); @@ -1029,68 +1122,74 @@ final class Wall extends VKAPIRequestHandler $this->fail(15, "Access denied"); } } - - function edit(int $owner_id, int $post_id, string $message = "", string $attachments = "", string $copyright = NULL, int $explicit = -1, int $from_group = 0, int $signed = 0) { + + public function edit(int $owner_id, int $post_id, string $message = "", string $attachments = "", string $copyright = null, int $explicit = -1, int $from_group = 0, int $signed = 0) + { $this->requireUser(); $this->willExecuteWriteAction(); $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio', 'poll', 'doc']); $final_attachments = []; - foreach($parsed_attachments as $attachment) { - if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && + foreach ($parsed_attachments as $attachment) { + if ($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && !(method_exists($attachment, 'getVoters') && $attachment->getOwner()->getId() != $this->getUser()->getId())) { $final_attachments[] = $attachment; } } - - if(empty($message) && sizeof($final_attachments) < 1) { + + if (empty($message) && sizeof($final_attachments) < 1) { $this->fail(-66, "Post will be empty, don't saving."); } - $post = (new PostsRepo)->getPostById($owner_id, $post_id, true); + $post = (new PostsRepo())->getPostById($owner_id, $post_id, true); - if(!$post || $post->isDeleted()) + if (!$post || $post->isDeleted()) { $this->fail(102, "Invalid post"); + } - if(!$post->canBeEditedBy($this->getUser())) + if (!$post->canBeEditedBy($this->getUser())) { $this->fail(7, "Access to editing denied"); + } - if(!empty($message) || (empty($message) && sizeof($final_attachments) > 0)) + if (!empty($message) || (empty($message) && sizeof($final_attachments) > 0)) { $post->setContent($message); - + } + $post->setEdited(time()); - if(!is_null($copyright) && !empty($copyright)) { - if($copyright == 'remove') { + if (!is_null($copyright) && !empty($copyright)) { + if ($copyright == 'remove') { $post->resetSource(); } else { try { $post->setSource($copyright); - } catch(\Throwable) {} + } catch (\Throwable) { + } } } - if($explicit != -1) { + if ($explicit != -1) { $post->setNsfw($explicit == 1); } - $wallOwner = ($owner_id > 0 ? (new UsersRepo)->get($owner_id) : (new ClubsRepo)->get($owner_id * -1)); + $wallOwner = ($owner_id > 0 ? (new UsersRepo())->get($owner_id) : (new ClubsRepo())->get($owner_id * -1)); $flags = 0; - if($from_group == 1 && $wallOwner instanceof Club && $wallOwner->canBeModifiedBy($this->getUser())) + if ($from_group == 1 && $wallOwner instanceof Club && $wallOwner->canBeModifiedBy($this->getUser())) { $flags |= 0b10000000; + } /*if($signed == 1) $flags |= 0b01000000;*/ $post->setFlags($flags); $post->save(true); - if($attachments == 'remove' || sizeof($final_attachments) > 0) { - foreach($post->getChildren() as $att) { - if(!($att instanceof Post)) { + if ($attachments == 'remove' || sizeof($final_attachments) > 0) { + foreach ($post->getChildren() as $att) { + if (!($att instanceof Post)) { $post->detach($att); } } - foreach($final_attachments as $attachment) { + foreach ($final_attachments as $attachment) { $post->attach($attachment); } } @@ -1098,38 +1197,43 @@ final class Wall extends VKAPIRequestHandler return ["post_id" => $post->getVirtualId()]; } - function editComment(int $comment_id, int $owner_id = 0, string $message = "", string $attachments = "") { + public function editComment(int $comment_id, int $owner_id = 0, string $message = "", string $attachments = "") + { $this->requireUser(); $this->willExecuteWriteAction(); - $comment = (new CommentsRepo)->get($comment_id); + $comment = (new CommentsRepo())->get($comment_id); $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio', 'doc']); $final_attachments = []; - foreach($parsed_attachments as $attachment) { - if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && + foreach ($parsed_attachments as $attachment) { + if ($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) && !(method_exists($attachment, 'getVoters') && $attachment->getOwner()->getId() != $this->getUser()->getId())) { $final_attachments[] = $attachment; } } - if(empty($message) && sizeof($final_attachments) < 1) + if (empty($message) && sizeof($final_attachments) < 1) { $this->fail(100, "Required parameter 'message' missing."); + } - if(!$comment || $comment->isDeleted()) + if (!$comment || $comment->isDeleted()) { $this->fail(102, "Invalid comment"); + } - if(!$comment->canBeEditedBy($this->getUser())) + if (!$comment->canBeEditedBy($this->getUser())) { $this->fail(15, "Access to editing comment denied"); - - if(!empty($message) || (empty($message) && sizeof($final_attachments) > 0)) + } + + if (!empty($message) || (empty($message) && sizeof($final_attachments) > 0)) { $comment->setContent($message); - + } + $comment->setEdited(time()); $comment->save(true); - if(sizeof($final_attachments) > 0) { + if (sizeof($final_attachments) > 0) { $comment->unwire(); - foreach($final_attachments as $attachment) { + foreach ($final_attachments as $attachment) { $comment->attach($attachment); } } @@ -1137,88 +1241,99 @@ final class Wall extends VKAPIRequestHandler return 1; } - function checkCopyrightLink(string $link): int + public function checkCopyrightLink(string $link): int { $this->requireUser(); try { - $result = check_copyright_link($link); - } catch(\InvalidArgumentException $e) { + $result = check_copyright_link($link); + } catch (\InvalidArgumentException $e) { $this->fail(3102, "Specified link is incorrect (can't find source)"); - } catch(\LengthException $e) { + } catch (\LengthException $e) { $this->fail(3103, "Specified link is incorrect (too long)"); - } catch(\LogicException $e) { + } catch (\LogicException $e) { $this->fail(3104, "Link is suspicious"); - } catch(\Throwable $e) { + } catch (\Throwable $e) { $this->fail(3102, "Specified link is incorrect"); } return 1; } - function pin(int $owner_id, int $post_id) + public function pin(int $owner_id, int $post_id) { $this->requireUser(); $this->willExecuteWriteAction(); - $post = (new PostsRepo)->getPostById($owner_id, $post_id); - if(!$post || $post->isDeleted()) + $post = (new PostsRepo())->getPostById($owner_id, $post_id); + if (!$post || $post->isDeleted()) { $this->fail(100, "One of the parameters specified was missing or invalid: post_id is undefined"); + } - if(!$post->canBePinnedBy($this->getUser())) + if (!$post->canBePinnedBy($this->getUser())) { return 0; - - if($post->isPinned()) + } + + if ($post->isPinned()) { return 1; - + } + $post->pin(); return 1; } - function unpin(int $owner_id, int $post_id) + public function unpin(int $owner_id, int $post_id) { $this->requireUser(); $this->willExecuteWriteAction(); - $post = (new PostsRepo)->getPostById($owner_id, $post_id); - if(!$post || $post->isDeleted()) + $post = (new PostsRepo())->getPostById($owner_id, $post_id); + if (!$post || $post->isDeleted()) { $this->fail(100, "One of the parameters specified was missing or invalid: post_id is undefined"); + } - if(!$post->canBePinnedBy($this->getUser())) + if (!$post->canBePinnedBy($this->getUser())) { return 0; - - if(!$post->isPinned()) + } + + if (!$post->isPinned()) { return 1; - + } + $post->unpin(); return 1; } - function getNearby(int $owner_id, int $post_id) + public function getNearby(int $owner_id, int $post_id) { $this->requireUser(); - $post = (new PostsRepo)->getPostById($owner_id, $post_id); - if(!$post || $post->isDeleted()) + $post = (new PostsRepo())->getPostById($owner_id, $post_id); + if (!$post || $post->isDeleted()) { $this->fail(100, "One of the parameters specified was missing or invalid: post_id is undefined"); + } - if(!$post->canBeViewedBy($this->getUser())) + if (!$post->canBeViewedBy($this->getUser())) { $this->fail(15, "Access denied"); + } $lat = $post->getLat(); $lon = $post->getLon(); - if(!$lat || !$lon) + if (!$lat || !$lon) { $this->fail(-97, "Post doesn't contains geo"); + } $query = file_get_contents(__DIR__ . "/../../Web/Models/sql/get-nearest-posts.tsql"); $_posts = \Chandler\Database\DatabaseConnection::i()->getContext()->query($query, $lat, $lon, $post->getId())->fetchAll(); $posts = []; - foreach($_posts as $post) { + foreach ($_posts as $post) { $distance = $post["distance"]; - $post = (new PostsRepo)->get($post["id"]); - if (!$post || $post->isDeleted() || !$post->canBeViewedBy($this->getUser())) continue; + $post = (new PostsRepo())->get($post["id"]); + if (!$post || $post->isDeleted() || !$post->canBeViewedBy($this->getUser())) { + continue; + } $owner = $post->getOwner(); $preview = mb_substr($post->getText(), 0, 50) . (strlen($post->getText()) > 50 ? "..." : ""); @@ -1233,14 +1348,15 @@ final class Wall extends VKAPIRequestHandler "verified" => $owner->isVerified(), ], "geo" => $post->getGeo(), - "distance" => $distance + "distance" => $distance, ]; } return $posts; } - private function getApiPhoto($attachment) { + private function getApiPhoto($attachment) + { return [ "type" => "photo", "photo" => [ @@ -1248,33 +1364,35 @@ final class Wall extends VKAPIRequestHandler "date" => $attachment->getPublicationTime()->timestamp(), "id" => $attachment->getVirtualId(), "owner_id" => $attachment->getOwner()->getId(), - "sizes" => !is_null($attachment->getVkApiSizes()) ? array_values($attachment->getVkApiSizes()) : NULL, + "sizes" => !is_null($attachment->getVkApiSizes()) ? array_values($attachment->getVkApiSizes()) : null, "text" => "", - "has_tags" => false - ] + "has_tags" => false, + ], ]; } - private function getApiPoll($attachment, $user) { - $answers = array(); - foreach($attachment->getResults()->options as $answer) { - $answers[] = (object)[ + private function getApiPoll($attachment, $user) + { + $answers = []; + foreach ($attachment->getResults()->options as $answer) { + $answers[] = (object) [ "id" => $answer->id, "rate" => $answer->pct, "text" => $answer->name, - "votes" => $answer->votes + "votes" => $answer->votes, ]; } - $userVote = array(); - foreach($attachment->getUserVote($user) as $vote) + $userVote = []; + foreach ($attachment->getUserVote($user) as $vote) { $userVote[] = $vote[0]; + } return [ "type" => "poll", "poll" => [ "multiple" => $attachment->isMultipleChoice(), - "end_date" => $attachment->endsAt() == NULL ? 0 : $attachment->endsAt()->timestamp(), + "end_date" => $attachment->endsAt() == null ? 0 : $attachment->endsAt()->timestamp(), "closed" => $attachment->hasEnded(), "is_board" => false, "can_edit" => false, @@ -1291,7 +1409,7 @@ final class Wall extends VKAPIRequestHandler "answer_ids" => $userVote, "answers" => $answers, "author_id" => $attachment->getOwner()->getId(), - ] + ], ]; } } diff --git a/VKAPI/Structures/Conversation.php b/VKAPI/Structures/Conversation.php index ad8951f3..8934c9c0 100644 --- a/VKAPI/Structures/Conversation.php +++ b/VKAPI/Structures/Conversation.php @@ -1,4 +1,7 @@ -payload = $message->simplify(); } - - function getLongPoolSummary(): object + + public function getLongPoolSummary(): object { return (object) [ "type" => "newMessage", "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(); - if($peer === $userId) + if ($peer === $userId) { $peer = $msg->getRecipient()->getId(); - + } + /* * Source: * https://github.com/danyadev/longpoll-doc @@ -43,7 +48,7 @@ class NewMessageEvent implements ILPEmitable [], # empty attachments $msg->getId() << 2, # id as random_id $peer, # conversation id - 0 # not edited yet + 0, # not edited yet ]; } } diff --git a/Web/Models/Entities/APIToken.php b/Web/Models/Entities/APIToken.php index 0cc53148..b4691644 100644 --- a/Web/Models/Entities/APIToken.php +++ b/Web/Models/Entities/APIToken.php @@ -1,5 +1,9 @@ -get($this->getRecord()->user); + return (new Users())->get($this->getRecord()->user); } - - function getSecret(): string + + public function getSecret(): string { return $this->getRecord()->secret; } - - function getFormattedToken(): string + + public function getFormattedToken(): string { return $this->getId() . "-" . chunk_split($this->getSecret(), 8, "-") . "jill"; } - function getPlatform(): ?string + public function getPlatform(): ?string { return $this->getRecord()->platform; } - - function isRevoked(): bool + + public function isRevoked(): bool { return $this->isDeleted(); } - - function setUser(User $user): void + + public function setUser(User $user): void { $this->stateChanges("user", $user->getId()); } - - function setSecret(string $secret): void + + public function setSecret(string $secret): void { throw new ISE("Setting secret manually is prohbited"); } - - function revoke(): void + + public function revoke(): void { $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))); - + } + parent::save(); } } diff --git a/Web/Models/Entities/Album.php b/Web/Models/Entities/Album.php index cc96cc0b..b2debf92 100644 --- a/Web/Models/Entities/Album.php +++ b/Web/Models/Entities/Album.php @@ -1,88 +1,94 @@ - "_avatar_album", 32 => "_wall_album", 64 => "_saved_photos_album", ]; - - function getCoverURL(): ?string + + public function getCoverURL(): ?string { $coverPhoto = $this->getCoverPhoto(); - if(!$coverPhoto) + if (!$coverPhoto) { return "/assets/packages/static/openvk/img/camera_200.png"; - + } + return $coverPhoto->getURL(); } - - function getCoverPhoto(): ?Photo + + public function getCoverPhoto(): ?Photo { $cover = $this->getRecord()->cover_photo; - if(!$cover) { + if (!$cover) { $photos = iterator_to_array($this->getPhotos(1, 1)); - $photo = $photos[0] ?? NULL; - if(!$photo || $photo->isDeleted()) - return NULL; - else + $photo = $photos[0] ?? null; + if (!$photo || $photo->isDeleted()) { + return null; + } else { 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); } - - function getPhotosCount(): int + + public function getPhotosCount(): int { return $this->size(); } - - function addPhoto(Photo $photo): void + + public function addPhoto(Photo $photo): void { $this->add($photo); } - - function removePhoto(Photo $photo): void + + public function removePhoto(Photo $photo): void { $this->remove($photo); } - - function hasPhoto(Photo $photo): bool + + public function hasPhoto(Photo $photo): bool { 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; } $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); } else { 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) []; @@ -93,17 +99,17 @@ class Album extends MediaCollection $res->title = $this->getName(); $res->description = $this->getDescription(); $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->privacy_comment = 1; $res->upload_by_admins_only = 1; $res->comments_disabled = 0; $res->can_upload = $this->canBeModifiedBy($user); # thisUser недоступен в entities - if($need_covers) { + if ($need_covers) { $res->thumb_src = $this->getCoverURL(); - if($photo_sizes) { - $res->sizes = !is_null($this->getCoverPhoto()) ? $this->getCoverPhoto()->getVkApiSizes() : NULL; + if ($photo_sizes) { + $res->sizes = !is_null($this->getCoverPhoto()) ? $this->getCoverPhoto()->getVkApiSizes() : null; } } diff --git a/Web/Models/Entities/Alias.php b/Web/Models/Entities/Alias.php index 99f7baae..c9e0cd44 100644 --- a/Web/Models/Entities/Alias.php +++ b/Web/Models/Entities/Alias.php @@ -1,4 +1,7 @@ -getRecord()->owner_id; } - function getType(): string + public function getType(): string { - if ($this->getOwnerId() < 0) + if ($this->getOwnerId() < 0) { return "club"; + } 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); } } diff --git a/Web/Models/Entities/Application.php b/Web/Models/Entities/Application.php index 48975645..116cc0f8 100644 --- a/Web/Models/Entities/Application.php +++ b/Web/Models/Entities/Application.php @@ -1,5 +1,9 @@ -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; } - - function getDescription(): string + + public function getDescription(): string { return $this->getRecord()->description; } - - function getAvatarUrl(): string + + public function getAvatarUrl(): string { $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"; - + } + $hash = $this->getRecord()->avatar_hash; - switch(OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["mode"]) { + switch (OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["mode"]) { default: case "default": case "basic": @@ -85,155 +91,168 @@ class Application extends RowModel ); } } - - function getNote(): ?Note + + public function getNote(): ?Note { - if(!$this->getRecord()->news) - return NULL; - - return (new Notes)->get($this->getRecord()->news); + if (!$this->getRecord()->news) { + return null; + } + + return (new Notes())->get($this->getRecord()->news); } - - function getNoteLink(): string + + public function getNoteLink(): string { $note = $this->getNote(); - if(!$note) + if (!$note) { return ""; - + } + return ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/note" . $note->getPrettyId(); } - - function getBalance(): float + + public function getBalance(): float { return $this->getRecord()->coins; } - - function getURL(): string + + public function getURL(): string { return $this->getRecord()->address; } - - function getOrigin(): string + + public function getOrigin(): string { $parsed = parse_url($this->getURL()); - + return ( ($parsed["scheme"] ?? "https") . "://" . ($parsed["host"] ?? "127.0.0.1") . ":" . ($parsed["port"] ?? "443") ); } - - function getUsersCount(): int + + public function getUsersCount(): int { $cx = DatabaseConnection::i()->getContext(); 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(); $entry = $cx->table("app_users")->where([ "app" => $this->getId(), "user" => $user->getId(), ])->fetch(); - - if(!$entry) - return NULL; - + + if (!$entry) { + return null; + } + return $entry->toArray(); } - - function getPermissions(User $user): array + + public function getPermissions(User $user): array { $permMask = 0; $installInfo = $this->getInstallationEntry($user); - if(!$installInfo) + if (!$installInfo) { $this->install($user); - else + } else { $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; } - - function isInstalledBy(User $user): bool + + public function isInstalledBy(User $user): bool { return !is_null($this->getInstallationEntry($user)); } - - function setNoteLink(?string $link): bool + + public function setNoteLink(?string $link): bool { - if(!$link) { - $this->stateChanges("news", NULL); - + if (!$link) { + $this->stateChanges("news", null); + return true; } - + preg_match("%note([0-9]+)_([0-9]+)$%", $link, $matches); - if(sizeof($matches) != 3) + if (sizeof($matches) != 3) { return false; - + } + $owner = is_null($this->getRecord()) ? $this->changes["owner"] : $this->getRecord()->owner; [, $ownerId, $vid] = $matches; - if($ownerId != $owner) + if ($ownerId != $owner) { return false; - - $note = (new Notes)->getNoteById((int) $ownerId, (int) $vid); - if(!$note) + } + + $note = (new Notes())->getNoteById((int) $ownerId, (int) $vid); + if (!$note) { return false; - + } + $this->stateChanges("news", $note->getId()); - + 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; - + } + try { $image = Image::fromFile($file["tmp_name"]); } catch (UnknownImageFileException $e) { return -2; } - + $hash = hash_file("adler32", $file["tmp_name"]); - if(!is_dir($this->getAvatarsDir() . substr($hash, 0, 2))) - if(!mkdir($this->getAvatarsDir() . substr($hash, 0, 2))) + if (!is_dir($this->getAvatarsDir() . substr($hash, 0, 2))) { + if (!mkdir($this->getAvatarsDir() . substr($hash, 0, 2))) { return -3; - + } + } + $image->resize(140, 140, Image::STRETCH); $image->save($this->getAvatarsDir() . substr($hash, 0, 2) . "/$hash" . "_app_avatar.png"); - + $this->stateChanges("avatar_hash", $hash); - + return 0; } - - function setPermission(User $user, string $perm, bool $enabled): bool + + public function setPermission(User $user, string $perm, bool $enabled): bool { $permMask = 0; $installInfo = $this->getInstallationEntry($user); - if(!$installInfo) + if (!$installInfo) { $this->install($user); - else + } else { $permMask = $installInfo["access"]; - + } + $index = array_search($perm, self::PERMS); - if($index === false) + if ($index === false) { return false; - + } + $permVal = 1 << $index; $permMask = $enabled ? ($permMask | $permVal) : ($permMask ^ $permVal); - + $cx = DatabaseConnection::i()->getContext(); $cx->table("app_users")->where([ "app" => $this->getId(), @@ -241,30 +260,30 @@ class Application extends RowModel ])->update([ "access" => $permMask, ]); - + return true; } - - function isEnabled(): bool + + public function isEnabled(): bool { return (bool) $this->getRecord()->enabled; } - - function enable(): void + + public function enable(): void { $this->stateChanges("enabled", 1); $this->save(); } - - function disable(): void + + public function disable(): void { $this->stateChanges("enabled", 0); $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->table("app_users")->insert([ "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->table("app_users")->where([ @@ -281,39 +300,42 @@ class Application extends RowModel "user" => $user->getId(), ])->delete(); } - - function addCoins(float $coins): float + + public function addCoins(float $coins): float { $res = $this->getBalance() + $coins; $this->stateChanges("coins", $res); $this->save(); - + return $res; } - - function withdrawCoins(): void + + public function withdrawCoins(): void { $balance = $this->getBalance(); $tax = ($balance / 100) * OPENVK_ROOT_CONF["openvk"]["preferences"]["apps"]["withdrawTax"]; - + $owner = $this->getOwner(); $owner->setCoins($owner->getCoins() + ($balance - $tax)); $this->setCoins(0.0); $this->save(); $owner->save(); } - - function delete(bool $softly = true): void + + public function delete(bool $softly = true): void { - if($softly) - throw new \UnexpectedValueException("Can't delete apps softly."); // why - + if ($softly) { + throw new \UnexpectedValueException("Can't delete apps softly."); + } // why + $cx = DatabaseConnection::i()->getContext(); $cx->table("app_users")->where("app", $this->getId())->delete(); - + parent::delete(false); } - function getPublicationTime(): string - { return tr("recently"); } -} \ No newline at end of file + public function getPublicationTime(): string + { + return tr("recently"); + } +} diff --git a/Web/Models/Entities/Attachable.php b/Web/Models/Entities/Attachable.php index a83c7383..5cdd54af 100644 --- a/Web/Models/Entities/Attachable.php +++ b/Web/Models/Entities/Attachable.php @@ -1,38 +1,42 @@ -getRecord()->id; } - - function getParents(): \Traversable + + public function getParents(): \Traversable { $sel = $this->getRecord() ->related("attachments.attachable_id") ->where("attachments.attachable_type", get_class($this)); - foreach($sel as $rel) { + foreach ($sel as $rel) { $repoName = $rel->target_type . "s"; $repoName = str_replace("Entities", "Repositories", $repoName); - $repo = new $repoName; - + $repo = new $repoName(); + yield $repo->get($rel->target_id); } } - + /** * Deletes together with all references. */ - function delete(bool $softly = true): void + public function delete(bool $softly = true): void { $this->getRecord() ->related("attachments.attachable_id") ->where("attachments.attachable_type", get_class($this)) ->delete(); - + parent::delete(); } } diff --git a/Web/Models/Entities/Audio.php b/Web/Models/Entities/Audio.php index 23941f4c..7e742db7 100644 --- a/Web/Models/Entities/Audio.php +++ b/Web/Models/Entities/Audio.php @@ -1,5 +1,9 @@ - 1, "Pop" => 2, "Rap" => 3, @@ -51,35 +55,40 @@ class Audio extends Media private function fileLength(string $filename): int { - if(!Shell::commandAvailable("ffmpeg") || !Shell::commandAvailable("ffprobe")) + if (!Shell::commandAvailable("ffmpeg") || !Shell::commandAvailable("ffprobe")) { throw new \Exception(); + } - $error = NULL; + $error = null; $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"); - else if(empty($streams) || ctype_space($streams)) + } elseif (empty($streams) || ctype_space($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); - + # check if audio has cover (attached_pic) 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"); + } $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"); + } $length = 0; - foreach($durations[1] as $duration) { + foreach ($durations[1] as $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"); - else + } else { $length = max($length, $duration); + } } return (int) round($length, 0, PHP_ROUND_HALF_EVEN); @@ -116,7 +125,7 @@ class Audio extends Media $ss, ]; - if(Shell::isPowershell()) { + if (Shell::isPowershell()) { Shell::powershell("-executionpolicy bypass", "-File", __DIR__ . "/../shell/processAudio.ps1", ...$args) ->start(); } else { @@ -126,58 +135,60 @@ class Audio extends Media # Wait until processAudio will consume the file $start = time(); - while(file_exists($filename)) - if(time() - $start > 5) + while (file_exists($filename)) { + if (time() - $start > 5) { throw new \RuntimeException("Timed out waiting FFMPEG"); + } + } - } catch(UnknownCommandException $ucex) { - exit(OPENVK_ROOT_CONF["openvk"]["debug"] ? "bash/pwsh is not installed" : VIDEOS_FRIENDLY_ERROR); - } + } catch (UnknownCommandException $ucex) { + exit(OPENVK_ROOT_CONF["openvk"]["debug"] ? "bash/pwsh is not installed" : VIDEOS_FRIENDLY_ERROR); + } return true; } - function getTitle(): string + public function getTitle(): string { return $this->getRecord()->name; } - function getPerformer(): string + public function getPerformer(): string { return $this->getRecord()->performer; } - function getPerformers(): array + public function getPerformers(): array { return explode(", ", $this->getRecord()->performer); } - function getName(): string + public function getName(): string { return $this->getPerformer() . " — " . $this->getTitle(); } - function getDownloadName(): string + public function getDownloadName(): string { return preg_replace('/[\\/:*?"<>|]/', '_', str_replace(' ', '_', $this->getName())); } - function getGenre(): ?string + public function getGenre(): ?string { 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; } - function getFormattedLength(): string + public function getFormattedLength(): string { $len = $this->getLength(); $mins = floor($len / 60); @@ -190,78 +201,83 @@ class Audio extends Media ); } - function getSegmentSize(): float + public function getSegmentSize(): float { return $this->getRecord()->segment_size; } - function getListens(): int + public function getListens(): int { 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; - if(!$this->isAvailable() || $disallowed) + if (!$this->isAvailable() || $disallowed) { return ovk_scheme(true) . $_SERVER["HTTP_HOST"] . ":" . $_SERVER["HTTP_PORT"] . "/assets/packages/static/openvk/audio/nomusic.mp3"; + } $key = bin2hex($this->getRecord()->token); 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(); } - function getKeys(): array + public function getKeys(): array { $keys[bin2hex($this->getRecord()->kid)] = bin2hex($this->getRecord()->key); return $keys; } - function isAnonymous(): bool + public function isAnonymous(): bool { return false; } - function isExplicit(): bool + public function isExplicit(): bool { return (bool) $this->getRecord()->explicit; } - function isWithdrawn(): bool + public function isWithdrawn(): bool { return (bool) $this->getRecord()->withdrawn; } - function isUnlisted(): bool + public function isUnlisted(): bool { return (bool) $this->getRecord()->unlisted; } # 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; + } # 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; + } try { $fragments = str_replace(".mpd", "_fragments", $this->getFileName()); $original = "original_" . bin2hex($this->getRecord()->token) . ".mp3"; - if(file_exists("$fragments/$original")) { + if (file_exists("$fragments/$original")) { # Original gets uploaded after fragments $this->stateChanges("processed", 0x01); @@ -275,7 +291,7 @@ class Audio extends Media return false; } - function isInLibraryOf($entity): bool + public function isInLibraryOf($entity): bool { return sizeof(DatabaseConnection::i()->getContext()->table("audio_relations")->where([ "entity" => $entity->getId() * ($entity instanceof Club ? -1 : 1), @@ -283,15 +299,17 @@ class Audio extends Media ])) != 0; } - function add($entity): bool + public function add($entity): bool { - if($this->isInLibraryOf($entity)) + if ($this->isInLibraryOf($entity)) { return false; + } $entityId = $entity->getId() * ($entity instanceof Club ? -1 : 1); $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"); + } $audioRels->insert([ "entity" => $entityId, @@ -301,10 +319,11 @@ class Audio extends Media return true; } - function remove($entity): bool + public function remove($entity): bool { - if(!$this->isInLibraryOf($entity)) + if (!$this->isInLibraryOf($entity)) { return false; + } DatabaseConnection::i()->getContext()->table("audio_relations")->where([ "entity" => $entity->getId() * ($entity instanceof Club ? -1 : 1), @@ -314,27 +333,27 @@ class Audio extends Media return true; } - function listen($entity, Playlist $playlist = NULL): bool + public function listen($entity, Playlist $playlist = null): bool { $listensTable = DatabaseConnection::i()->getContext()->table("audio_listens"); $lastListen = $listensTable->where([ "entity" => $entity->getRealId(), "audio" => $this->getId(), ])->order("index DESC")->fetch(); - - if(!$lastListen || (time() - $lastListen->time >= $this->getLength())) { + + if (!$lastListen || (time() - $lastListen->time >= $this->getLength())) { $listensTable->insert([ "entity" => $entity->getRealId(), "audio" => $this->getId(), "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->save(); - if($playlist) { + if ($playlist) { $playlist->incrementListens(); $playlist->save(); } @@ -380,7 +399,7 @@ class Audio extends Media * @param ?User $user user, relative to whom "added", "editable" will be set * @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->unique_id = base64_encode((string) $this->getId()); @@ -388,19 +407,21 @@ class Audio extends Media $obj->artist = $this->getPerformer(); $obj->title = $this->getTitle(); $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->manifest = false; $obj->keys = false; $obj->genre_id = $obj->genre = self::vkGenres[$this->getGenre() ?? ""] ?? 18; # return Other if no match $obj->genre_str = $this->getGenre(); $obj->owner_id = $this->getOwner()->getId(); - if($this->getOwner() instanceof Club) + if ($this->getOwner() instanceof Club) { $obj->owner_id *= -1; + } - $obj->lyrics = NULL; - if(!is_null($this->getLyrics())) + $obj->lyrics = null; + if (!is_null($this->getLyrics())) { $obj->lyrics = $this->getId(); + } $obj->added = $user && $this->isInLibraryOf($user); $obj->editable = $user && $this->canBeModifiedBy($user); @@ -408,7 +429,7 @@ class Audio extends Media $obj->explicit = $this->isExplicit(); $obj->withdrawn = $this->isWithdrawn(); $obj->ready = $this->isAvailable() && !$obj->withdrawn; - if($obj->ready) { + if ($obj->ready) { $obj->url = $this->getOriginalURL($forceURLExposure); $obj->manifest = $this->getURL(); $obj->keys = $this->getKeys(); @@ -417,54 +438,62 @@ class Audio extends Media 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 - if($oid <= 0) + if ($oid <= 0) { throw new \OutOfRangeException("Only users can be owners of audio!"); + } $this->stateChanges("owner", $oid); } - function setGenre(string $genre): void + public function setGenre(string $genre): void { - if(!in_array($genre, Audio::genres)) { - $this->stateChanges("genre", NULL); + if (!in_array($genre, Audio::genres)) { + $this->stateChanges("genre", null); return; } $this->stateChanges("genre", $genre); } - function setCopyrightStatus(bool $withdrawn = true): void { + public function setCopyrightStatus(bool $withdrawn = true): void + { $this->stateChanges("withdrawn", $withdrawn); } - function setSearchability(bool $searchable = true): void { + public function setSearchability(bool $searchable = true): void + { $this->stateChanges("unlisted", !$searchable); } - function setToken(string $tok): void { + public function setToken(string $tok): void + { 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."); } - function setKey(string $key): void { + public function setKey(string $key): void + { 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."); } - function setSegment_Size(int $len): void { + public function setSegment_Size(int $len): void + { 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->table("audio_relations")->where("audio", $this->getId()) diff --git a/Web/Models/Entities/Ban.php b/Web/Models/Entities/Ban.php index 3962c6cb..6d600a57 100644 --- a/Web/Models/Entities/Ban.php +++ b/Web/Models/Entities/Ban.php @@ -1,5 +1,9 @@ -getRecord()->id; } - function getReason(): ?string + public function getReason(): ?string { 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; } - function getEndTime(): int + public function getEndTime(): int { return $this->getRecord()->exp; } - function getTime(): int + public function getTime(): int { return $this->getRecord()->time; } - function isPermanent(): bool + public function isPermanent(): bool { return $this->getEndTime() === 0; } - function isRemovedManually(): bool + public function isRemovedManually(): bool { return (bool) $this->getRecord()->removed_manually; } - function isOver(): bool + public function isOver(): bool { 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); } } diff --git a/Web/Models/Entities/BannedLink.php b/Web/Models/Entities/BannedLink.php index 09c42e39..c658225a 100644 --- a/Web/Models/Entities/BannedLink.php +++ b/Web/Models/Entities/BannedLink.php @@ -1,5 +1,9 @@ -getRecord()->id; } - function getDomain(): string + public function getDomain(): string { return $this->getRecord()->domain; } - function getReason(): string + public function getReason(): string { 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"] ? 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"]); } - 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; } diff --git a/Web/Models/Entities/Club.php b/Web/Models/Entities/Club.php index 2e90937f..01d75412 100644 --- a/Web/Models/Entities/Club.php +++ b/Web/Models/Entities/Club.php @@ -1,5 +1,9 @@ -getRecord()->id; } - - function getAvatarPhoto(): ?Photo + + public function getAvatarPhoto(): ?Photo { - $avAlbum = (new Albums)->getClubAvatarAlbum($this); + $avAlbum = (new Albums())->getClubAvatarAlbum($this); $avCount = $avAlbum->getPhotosCount(); $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"]; - if(!$avPhoto) + if (!$avPhoto) { $avPhoto = $this->getAvatarPhoto(); - + } + 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; } - - function getAvatarLink(): string + + public function getAvatarLink(): string { $avPhoto = $this->getAvatarPhoto(); - if(!$avPhoto) return "javascript:void(0)"; - + if (!$avPhoto) { + return "javascript:void(0)"; + } + $pid = $avPhoto->getPrettyId(); - $aid = (new Albums)->getClubAvatarAlbum($this)->getId(); - + $aid = (new Albums())->getClubAvatarAlbum($this)->getId(); + 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(); - else + } else { return "/club" . $this->getId(); + } } - - function getName(): string + + public function getName(): string { return $this->getRecord()->name; } - - function getCanonicalName(): string + + public function getCanonicalName(): string { 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; } - function isOwnerHidden(): bool + public function isOwnerHidden(): bool { return (bool) $this->getRecord()->owner_hidden; } - - function isOwnerClubPinned(): bool + + public function isOwnerClubPinned(): bool { return (bool) $this->getRecord()->owner_club_pinned; } - function getDescription(): ?string + public function getDescription(): ?string { 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)); - else - return NULL; + } else { + return null; + } } - - function getShortCode(): ?string + + public function getShortCode(): ?string { return $this->getRecord()->shortcode; } - - function getBanReason(): ?string + + public function getBanReason(): ?string { return $this->getRecord()->block_reason; } - - function getOpennesStatus(): int + + public function getOpennesStatus(): int { return $this->getRecord()->closed; } - function getAdministratorsListDisplay(): int + public function getAdministratorsListDisplay(): int { return $this->getRecord()->administrators_list_display; } - - function isEveryoneCanCreateTopics(): bool + + public function isEveryoneCanCreateTopics(): bool { return (bool) $this->getRecord()->everyone_can_create_topics; } - function isDisplayTopicsAboveWallEnabled(): bool + public function isDisplayTopicsAboveWallEnabled(): bool { return (bool) $this->getRecord()->display_topics_above_wall; } - function isHideFromGlobalFeedEnabled(): bool + public function isHideFromGlobalFeedEnabled(): bool { return (bool) $this->getRecord()->hide_from_global_feed; } - function isHidingFromGlobalFeedEnforced(): bool + public function isHidingFromGlobalFeedEnforced(): bool { return (bool) $this->getRecord()->enforce_hiding_from_global_feed; } - function getType(): int + public function getType(): int { return $this->getRecord()->type; } - - function isVerified(): bool + + public function isVerified(): bool { return (bool) $this->getRecord()->verified; } - - function isBanned(): bool + + public function isBanned(): bool { 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(!preg_match("%^[a-z][a-z0-9\\.\\_]{0,30}[a-z0-9]$%", $code)) + if (!is_null($code)) { + if (!preg_match("%^[a-z][a-z0-9\\.\\_]{0,30}[a-z0-9]$%", $code)) { 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; - if(\Chandler\MVC\Routing\Router::i()->getMatchingRoute("/$code")[0]->presenter !== "UnknownTextRouteStrategy") + } + if (\Chandler\MVC\Routing\Router::i()->getMatchingRoute("/$code")[0]->presenter !== "UnknownTextRouteStrategy") { return false; - + } + $pUser = DB::i()->getContext()->table("profiles")->where("shortcode", $code)->fetch(); - if(!is_null($pUser)) + if (!is_null($pUser)) { return false; + } } - + $this->stateChanges("shortcode", $code); 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"); + } $this->stateChanges("wall", $type); } - - function isSubscriptionAccepted(User $user): bool + + public function isSubscriptionAccepted(User $user): bool { return !is_null($this->getRecord()->related("subscriptions.follower")->where([ "follower" => $this->getId(), "target" => $user->getId(), - ])->fetch());; + ])->fetch()); + ; } - - function getPostViewStats(bool $unique = false): ?array + + public function getPostViewStats(bool $unique = false): ?array { $edb = eventdb(); - if(!$edb) - return NULL; - + if (!$edb) { + return null; + } + $subs = []; $viral = []; $total = []; - for($i = 1; $i < 8; $i++) { + for ($i = 1; $i < 8; $i++) { $begin = strtotime("-" . $i . "day midnight"); $end = $i === 1 ? time() + 10 : strtotime("-" . ($i - 1) . "day midnight"); - + $query = "SELECT COUNT(" . ($unique ? "DISTINCT profile" : "*") . ") AS cnt FROM postViews"; $query .= " WHERE `group`=1 AND owner=" . $this->getId(); $query .= " AND timestamp > $begin AND timestamp < $end"; - + $sub = $edb->getConnection()->query("$query AND NOT subscribed=0")->fetch()->cnt; $vir = $edb->getConnection()->query("$query AND subscribed=0")->fetch()->cnt; $subs[] = $sub; $viral[] = $vir; $total[] = $sub + $vir; } - + return [ "total" => [ "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([ "target" => $this->getId(), "model" => static::class, "follower" => $user->getId(), ])->fetch()); - + 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"); - - if($this->getOpennesStatus() === static::OPEN) { + + if ($this->getOpennesStatus() === static::OPEN) { $query = $query->where("model", "openvk\\Web\\Models\\Entities\\Club")->order($sort); } else { return false; } - + return $query->group("follower"); } - - function getFollowersCount(): int + + public function getFollowersCount(): int { 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); - - foreach($rels as $rel) { - $rel = (new Users)->get($rel->follower); - if(!$rel) continue; - + + foreach ($rels as $rel) { + $rel = (new Users())->get($rel->follower); + if (!$rel) { + continue; + } + yield $rel; } } - function getSuggestedPostsCount(User $user = NULL) + public function getSuggestedPostsCount(User $user = null) { $count = 0; - if(is_null($user)) - return NULL; + if (is_null($user)) { + return null; + } - if($this->canBeModifiedBy($user)) - $count = (new Posts)->getSuggestedPostsCount($this->getId()); - else - $count = (new Posts)->getSuggestedPostsCountByUser($this->getId(), $user->getId()); + if ($this->canBeModifiedBy($user)) { + $count = (new Posts())->getSuggestedPostsCount($this->getId()); + } else { + $count = (new Posts())->getSuggestedPostsCountByUser($this->getId(), $user->getId()); + } 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); - if($ignoreHidden) + if ($ignoreHidden) { $rels = $rels->where("hidden", false); - - foreach($rels as $rel) { - $rel = (new Managers)->get($rel->id); - if(!$rel) continue; + } + + foreach ($rels as $rel) { + $rel = (new Managers())->get($rel->id); + if (!$rel) { + continue; + } 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()) - return NULL; + if ($ignoreHidden && $manager !== null && $manager->isHidden()) { + return null; + } 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")) + 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([ "club" => $this->getId(), @@ -370,103 +399,107 @@ class Club extends RowModel "comment" => $comment, ]); } - - function removeManager(User $user): void + + public function removeManager(User $user): void { DB::i()->getContext()->table("group_coadmins")->where([ "club" => $this->getId(), "user" => $user->getId(), ])->delete(); } - - function canBeModifiedBy(User $user): bool + + public function canBeModifiedBy(User $user): bool { $id = $user->getId(); - if($this->getOwner()->getId() === $id) + if ($this->getOwner()->getId() === $id) { return true; - + } + return !is_null($this->getRecord()->related("group_coadmins.club")->where("user", $id)->fetch()); } - function getWebsite(): ?string - { - return $this->getRecord()->website; - } + public function getWebsite(): ?string + { + return $this->getRecord()->website; + } - function ban(string $reason): void + public function ban(string $reason): void { $this->setBlock_Reason($reason); $this->save(); } - function unban(): void + public function unban(): void { $this->setBlock_Reason(null); $this->save(); } - function canBeViewedBy(?User $user = NULL) + public function canBeViewedBy(?User $user = null) { return is_null($this->getBanReason()); } - function getAlert(): ?string + public function getAlert(): ?string { return $this->getRecord()->alert; } - function getRealId(): int + public function getRealId(): int { return $this->getId() * -1; } - function isEveryoneCanUploadAudios(): bool + public function isEveryoneCanUploadAudios(): bool { return (bool) $this->getRecord()->everyone_can_upload_audios; } - function canUploadAudio(?User $user): bool + public function canUploadAudio(?User $user): bool { - if(!$user) - return NULL; + if (!$user) { + return null; + } return $this->isEveryoneCanUploadAudios() || $this->canBeModifiedBy($user); } - function canUploadDocs(?User $user): bool + public function canUploadDocs(?User $user): bool { - if(!$user) + if (!$user) { return false; + } 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->id = $this->getId(); $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->type = 'group'; - $res->is_member = $user ? (int)$this->getSubscriptionStatus($user) : 0; - $res->deactivated = NULL; + $res->is_member = $user ? (int) $this->getSubscriptionStatus($user) : 0; + $res->deactivated = null; $res->can_access_closed = true; - if(!is_array($fields)) + if (!is_array($fields)) { $fields = explode(',', $fields); - + } + $avatar_photo = $this->getAvatarPhoto(); - foreach($fields as $field) { - switch($field) { + foreach ($fields as $field) { + switch ($field) { case 'verified': - $res->verified = (int)$this->isVerified(); + $res->verified = (int) $this->isVerified(); break; case 'site': $res->site = $this->getWebsite(); @@ -500,9 +533,4 @@ class Club extends RowModel return $res; } - - use Traits\TBackDrops; - use Traits\TSubscribable; - use Traits\TAudioStatuses; - use Traits\TIgnorable; } diff --git a/Web/Models/Entities/Comment.php b/Web/Models/Entities/Comment.php index acd5d7b5..273debf3 100644 --- a/Web/Models/Entities/Comment.php +++ b/Web/Models/Entities/Comment.php @@ -1,5 +1,9 @@ -getRecord()->id; + return (string) $this->getRecord()->id; } - - function getVirtualId(): int + + public function getVirtualId(): int { return 0; } - - function getTarget(): ?Postable + + public function getTarget(): ?Postable { $entityClassName = $this->getRecord()->model; $repoClassName = str_replace("Entities", "Repositories", $entityClassName) . "s"; - $entity = (new $repoClassName)->get($this->getRecord()->target); - + $entity = (new $repoClassName())->get($this->getRecord()->target); + return $entity; } - function getPageURL(): string + public function getPageURL(): string { return '#'; } /** * May return fake owner (group), if flags are [1, (*)] - * + * * @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($this->getTarget() instanceof Post) - return (new Clubs)->get(abs($this->getTarget()->getTargetWall())); + if ($honourFlags && $this->isPostedOnBehalfOfGroup()) { + if ($this->getTarget() instanceof Post) { + return (new Clubs())->get(abs($this->getTarget()->getTargetWall())); + } - if($this->getTarget() instanceof Topic) + if ($this->getTarget() instanceof Topic) { return $this->getTarget()->getClub(); + } } 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 $this->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); } - 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) []; @@ -72,93 +79,97 @@ class Comment extends Post $res->text = $this->getText(false); $res->attachments = []; $res->parents_stack = []; - - if(!is_null($note)) { + + if (!is_null($note)) { $res->uid = $this->getOwner()->getId(); $res->nid = $note->getId(); $res->oid = $note->getOwner()->getId(); } - foreach($this->getChildren() as $attachment) { - if($attachment->isDeleted()) + foreach ($this->getChildren() as $attachment) { + if ($attachment->isDeleted()) { continue; - - if($attachment instanceof \openvk\Web\Models\Entities\Photo) { + } + + if ($attachment instanceof \openvk\Web\Models\Entities\Photo) { $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()); } } - if($need_likes) { + if ($need_likes) { $res->count = $this->getLikesCount(); - $res->user_likes = (int)$this->hasLikeFrom($user); + $res->user_likes = (int) $this->hasLikeFrom($user); $res->can_like = 1; } return $res; } - function getURL(): string + public function getURL(): string { 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 $this->getTarget()->canBeViewedBy($user); } - function isFromPostAuthor($target = NULL) + public function isFromPostAuthor($target = null) { - if(!$target) + if (!$target) { $target = $this->getTarget(); + } $target_owner = $target->getOwner(); $comment_owner = $this->getOwner(); - - if($target_owner->getRealId() === $comment_owner->getRealId()) + + if ($target_owner->getRealId() === $comment_owner->getRealId()) { return true; + } # TODO: make it work with signer_id return false; } - - function toNotifApiStruct() + + public function toNotifApiStruct() { - $res = (object)[]; - + $res = (object) []; + $res->id = $this->getId(); $res->owner_id = $this->getOwner()->getId(); $res->date = $this->getPublicationTime()->timestamp(); $res->text = $this->getText(false); - $res->post = NULL; # todo + $res->post = null; # todo return $res; } - - function canBeEditedBy(?User $user = NULL): bool + + public function canBeEditedBy(?User $user = null): bool { - if(!$user) + if (!$user) { return false; - + } + return $user->getId() == $this->getOwner(false)->getId(); } - function getTargetURL(): string + public function getTargetURL(): string { $target = $this->getTarget(); $target_name = 'wall'; - if(!$target) { + if (!$target) { return '/404'; } - switch(get_class($target)) { + switch (get_class($target)) { case 'openvk\Web\Models\Entities\Note': $target_name = 'note'; break; diff --git a/Web/Models/Entities/Correspondence.php b/Web/Models/Entities/Correspondence.php index a972425e..2dae1083 100644 --- a/Web/Models/Entities/Correspondence.php +++ b/Web/Models/Entities/Correspondence.php @@ -1,5 +1,9 @@ -correspondents = [$correspondent, $anotherCorrespondent]; $this->messages = DatabaseConnection::i()->getContext()->table("messages"); } - + /** * Get /im?sel url. - * + * * @returns string - URL */ - function getURL(): string + public function getURL(): string { $id = $this->correspondents[1]->getId(); $id = get_class($this->correspondents[1]) === 'openvk\Web\Models\Entities\Club' ? $id * -1 : $id; - + return "/im?sel=$id"; } - - function getID(): int + + public function getID(): int { $id = $this->correspondents[1]->getId(); $id = get_class($this->correspondents[1]) === 'openvk\Web\Models\Entities\Club' ? $id * -1 : $id; - + return $id; } - + /** * Get correspondents as array. - * + * * @returns RowModel[] Array of correspondents (usually two) */ - function getCorrespondents(): array + public function getCorrespondents(): array { return $this->correspondents; } - + /** * Fetch messages. - * + * * Fetch messages on per page basis. - * + * * @param $cap - page (defaults to first) * @param $limit - messages per page (defaults to default per page count) * @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"); $params = [ [get_class($this->correspondents[0]), get_class($this->correspondents[1])], [$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]); - - if ($limit === NULL) - DatabaseConnection::i()->getConnection()->query("UPDATE messages SET unread = 0 WHERE sender_id = ".$this->correspondents[1]->getId()); - - if(is_null($cap)) { + + if ($limit === null) { + DatabaseConnection::i()->getConnection()->query("UPDATE messages SET unread = 0 WHERE sender_id = " . $this->correspondents[1]->getId()); + } + + if (is_null($cap)) { $query = str_replace("\n AND (`id` > ?)", "", $query); } else { - if($capBehavior === 1) + if ($capBehavior === 1) { $query = str_replace("\n AND (`id` > ?)", "\n AND (`id` < ?)", $query); - + } + array_unshift($params, $cap); } - - if(is_null($padding)) + + if (is_null($padding)) { $query = str_replace("\nOFFSET\n?", "", $query); - else + } else { $params[] = $padding; - - if($reverse) + } + + if ($reverse) { $query = str_replace("`created` DESC", "`created` ASC", $query); - + } + $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 - + return new Message($message); }, iterator_to_array($msgs)); - + return $msgs; } - + /** * Get last message from correspondence. - * + * * @returns Message|null - message, if any */ - function getPreviewMessage(): ?Message + public function getPreviewMessage(): ?Message { - $messages = $this->getMessages(1, NULL, 1, 0); - return $messages[0] ?? NULL; + $messages = $this->getMessages(1, null, 1, 0); + return $messages[0] ?? null; } - + /** * Send message. - * + * * @deprecated * @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) { - $user = (new Users)->getByChandlerUser(Authenticator::i()->getUser()); - if(!$user) + if (!$dontReverse) { + $user = (new Users())->getByChandlerUser(Authenticator::i()->getUser()); + if (!$user) { return false; + } } - + $ids = [$this->correspondents[0]->getId(), $this->correspondents[1]->getId()]; $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); $classes = array_reverse($classes); } - + $message->setSender_Id($ids[0]); $message->setRecipient_Id($ids[1]); $message->setSender_Type($classes[0]); @@ -163,15 +172,15 @@ class Correspondence $message->setCreated(time()); $message->setUnread(1); $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); (SignalManager::i())->triggerEvent($event, $ids[1]); } - + return $message; } } diff --git a/Web/Models/Entities/Document.php b/Web/Models/Entities/Document.php index 6f6bf369..286f9c0b 100644 --- a/Web/Models/Entities/Document.php +++ b/Web/Models/Entities/Document.php @@ -1,5 +1,9 @@ -getBaseDir() . substr($hash, 0, 2); - if(!is_dir($dir)) + if (!is_dir($dir)) { mkdir($dir); - + } + return "$dir/$hash." . $this->getFileExtension(); } - function getURL(): string + public function getURL(): string { $hash = $this->getRecord()->hash; $filetype = $this->getFileExtension(); - - switch(OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["mode"]) { + + switch (OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["mode"]) { default: case "default": case "basic": return "http://" . $_SERVER['HTTP_HOST'] . "/blob_" . substr($hash, 0, 2) . "/$hash.$filetype"; - break; + break; case "accelerated": return "http://" . $_SERVER['HTTP_HOST'] . "/openvk-datastore/$hash.$filetype"; - break; + break; case "server": $settings = (object) OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["server"]; return ( @@ -57,7 +62,7 @@ class Document extends Media $settings->path . 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 { - $preview_photo = new Photo; + $preview_photo = new Photo(); $preview_photo->setOwner($owner); $preview_photo->setDescription("internal use"); $preview_photo->setCreated(time()); @@ -79,7 +84,7 @@ class Document extends Media "error" => 0, ]); $preview_photo->save(); - $this->stateChanges("preview", "photo_".$preview_photo->getId()); + $this->stateChanges("preview", "photo_" . $preview_photo->getId()); return true; } @@ -90,25 +95,29 @@ class Document extends Media 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"); - + } + $original_name = $file["name"]; $file_format = end(explode(".", $original_name)); $file_size = $file["size"]; $type = Document::detectTypeByFormat($file_format); - if(!$file_format) + if (!$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"); + } - 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"); + } $hash = hash_file("whirlpool", $file["tmp_name"]); $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("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->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; } - 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; } - function isUnsafe(): bool + public function isUnsafe(): bool { return false; } - function isAnonymous(): bool + public function isAnonymous(): bool { return false; } - - function isPrivate(): bool + + public function isPrivate(): bool { return $this->getFolder() == Document::VKAPI_FOLDER_PRIVATE; } - function isImage(): bool + public function isImage(): bool { return in_array($this->getVKAPIType(), [3, 4]); } - function isBook(): bool + public function isBook(): bool { return in_array($this->getFileExtension(), ["pdf"]); } - function isAudio(): bool + public function isAudio(): bool { return in_array($this->getVKAPIType(), [Document::VKAPI_TYPE_AUDIO]); } - function isGif(): bool + public function isGif(): bool { return $this->getVKAPIType() == 3; } - function isCopiedBy($user = NULL): bool + public function isCopiedBy($user = null): bool { - if(!$user) + if (!$user) { return false; + } - if($user->getRealId() === $this->getOwnerID()) + if ($user->getRealId() === $this->getOwnerID()) { return true; - + } + return DatabaseConnection::i()->getContext()->table("documents")->where([ "owner" => $user->getRealId(), "copy_of" => $this->getId(), @@ -196,19 +207,19 @@ class Document extends Media ])->count() > 0; } - function copy(User $user): Document + public function copy(User $user): Document { $item = DatabaseConnection::i()->getContext()->table("documents")->where([ "owner" => $user->getId(), "copy_of" => $this->getId(), ]); - if($item->count() > 0) { + if ($item->count() > 0) { $older = new Document($item->fetch()); } $this_document_array = $this->getRecord()->toArray(); - $new_document = new Document; + $new_document = new Document(); $new_document->setOwner($user->getId()); $new_document->updateHash($this_document_array["hash"]); $new_document->setOwner_hidden(1); @@ -228,21 +239,21 @@ class Document extends Media return $new_document; } - function setTags(?string $tags): bool + public function setTags(?string $tags): bool { - if(is_null($tags)) { - $this->stateChanges("tags", NULL); + if (is_null($tags)) { + $this->stateChanges("tags", null); return true; } $parsed = explode(",", $tags); - if(sizeof($parsed) < 1 || $parsed[0] == "") { - $this->stateChanges("tags", NULL); + if (sizeof($parsed) < 1 || $parsed[0] == "") { + $this->stateChanges("tags", null); return true; } $result = ""; - foreach($parsed as $tag) { + foreach ($parsed as $tag) { $result .= trim($tag) . ($tag != end($parsed) ? "," : ''); } @@ -250,99 +261,101 @@ class Document extends Media return true; } - function getOwner(bool $real = false): RowModel + public function getOwner(bool $real = false): RowModel { $oid = (int) $this->getRecord()->owner; - if($oid > 0) - return (new Users)->get($oid); - else - return (new Clubs)->get($oid * -1); + if ($oid > 0) { + return (new Users())->get($oid); + } else { + 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->getRecord()->format; } - function getPrettyId(): string + public function getPrettyId(): string { return $this->getVirtualId() . "_" . $this->getId(); } - function getPrettiestId(): string + public function getPrettiestId(): string { return $this->getVirtualId() . "_" . $this->getId() . "_" . $this->getAccessKey(); } - function getOriginal(): Document + public function getOriginal(): Document { return $this->getRecord()->copy_of; } - function getName(): string + public function getName(): string { return $this->getRecord()->name; } - function getOriginalName(): string + public function getOriginalName(): string { return $this->getRecord()->original_name; } - function getVKAPIType(): int + public function getVKAPIType(): int { return $this->getRecord()->type; } - function getFolder(): int + public function getFolder(): int { return $this->getRecord()->folder_id; } - function getTags(): array + public function getTags(): array { $tags = $this->getRecord()->tags; - if(!$tags) + if (!$tags) { return []; - + } + return explode(",", $tags ?? ""); } - function getFilesize(): int + public function getFilesize(): int { return $this->getRecord()->filesize; } - function getPreview(): ?RowModel + public function getPreview(): ?RowModel { $preview_array = $this->getRecord()->preview; $preview = explode(",", $this->getRecord()->preview)[0]; - $model = NULL; + $model = null; $exploded = explode("_", $preview); - switch($exploded[0]) { + switch ($exploded[0]) { case "photo": - $model = (new Photos)->get((int)$exploded[1]); + $model = (new Photos())->get((int) $exploded[1]); break; } return $model; } - function getOwnerID(): int + public function getOwnerID(): int { return $this->getRecord()->owner; } - function toApiPreview(): object + public function toApiPreview(): object { $preview = $this->getPreview(); - if($preview instanceof Photo) { - return (object)[ + if ($preview instanceof Photo) { + return (object) [ "photo" => [ "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; + } + + 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(); } - 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->owner_id = $this->getVirtualId(); $res->title = $this->getName(); @@ -378,30 +393,33 @@ class Document extends Media $res->folder_id = (int) $this->getFolder(); $res->access_key = $this->getAccessKey(); $res->private_url = ""; - if($user) + if ($user) { $res->can_manage = $this->canBeModifiedBy($user); + } - if($this->hasPreview()) + if ($this->hasPreview()) { $res->preview = $this->toApiPreview(); + } - if($return_tags) + if ($return_tags) { $res->tags = $this->getTags(); + } 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->table("documents")->where("copy_of", $this->getId())->delete(); } 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": return 1; case "zip": case "rar": case "7z": diff --git a/Web/Models/Entities/EmailChangeVerification.php b/Web/Models/Entities/EmailChangeVerification.php index e9b92db1..6e283efc 100644 --- a/Web/Models/Entities/EmailChangeVerification.php +++ b/Web/Models/Entities/EmailChangeVerification.php @@ -1,5 +1,9 @@ -getRecord()->new_email; } diff --git a/Web/Models/Entities/EmailVerification.php b/Web/Models/Entities/EmailVerification.php index cfd057f9..e3b690d0 100755 --- a/Web/Models/Entities/EmailVerification.php +++ b/Web/Models/Entities/EmailVerification.php @@ -1,10 +1,14 @@ -getRecord()->internal_name; } - - function getPrice(): int + + public function getPrice(): int { return $this->getRecord()->price; } - - function getUsages(): int + + public function getUsages(): int { return $this->getRecord()->usages; } - - function getUsagesBy(User $user, ?int $since = NULL): int + + public function getUsagesBy(User $user, ?int $since = null): int { $sent = $this->getRecord() ->related("gift_user_relations.gift") ->where("sender", $user->getId()) ->where("sent >= ?", $since ?? $this->getRecord()->limit_period ?? 0); - + 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 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: case static::IMAGE_BINARY: return $this->getRecord()->image ?? ""; @@ -66,99 +71,100 @@ class Gift extends RowModel break; } } - - function getLimit(): float + + public function getLimit(): float { $limit = $this->getRecord()->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); } - - function canUse(User $user): bool + + public function canUse(User $user): bool { return $this->getUsagesLeft($user) > 0; } - - function isFree(): bool + + public function isFree(): bool { return $this->getPrice() === 0; } - - function used(): void + + public function used(): void { $this->stateChanges("usages", $this->getUsages() + 1); $this->save(); } - - function setName(string $name): void + + public function setName(string $name): void { $this->stateChanges("internal_name", $name); } - - function setImage(string $file): bool + + public function setImage(string $file): bool { $imgBlob; try { $image = Image::fromFile($file); $image->resize(512, 512, Image::SHRINK_ONLY); - + $imgBlob = $image->toString(Image::PNG); - } catch(ImageException $ex) { + } catch (ImageException $ex) { return false; } - - if(strlen($imgBlob) > (2**24 - 1)) { + + if (strlen($imgBlob) > (2 ** 24 - 1)) { return false; } else { $this->stateChanges("updated", time()); $this->stateChanges("image", $imgBlob); } - + 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 = $limit === INF ? NULL : (int) $limit; + $limit = $limit === INF ? null : (int) $limit; $this->stateChanges("limit", $limit); - - if(!$limit) { - $this->stateChanges("limit_period", NULL); + + if (!$limit) { + $this->stateChanges("limit_period", null); return; } - - switch($periodBehaviour) { + + switch ($periodBehaviour) { default: case static::PERIOD_IGNORE: break; - + case static::PERIOD_SET: $this->stateChanges("limit_period", time()); break; - + 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()); - + } + break; } } - - function delete(bool $softly = true): void + + public function delete(bool $softly = true): void { $this->getRecord()->related("gift_relations.gift")->delete(); - + parent::delete($softly); } } diff --git a/Web/Models/Entities/GiftCategory.php b/Web/Models/Entities/GiftCategory.php index 45687057..2edee69b 100644 --- a/Web/Models/Entities/GiftCategory.php +++ b/Web/Models/Entities/GiftCategory.php @@ -1,5 +1,9 @@ -getRecord() ->related("gift_categories_locales.category") ->where("language", $language); } - + private function createLocalizationIfNotExists(string $language): void { - if(!is_null($this->getLocalization($language)->fetch())) + if (!is_null($this->getLocalization($language)->fetch())) { return; - + } + DB::i()->getContext()->table("gift_categories_locales")->insert([ "category" => $this->getId(), "language" => $language, @@ -28,8 +33,8 @@ class GiftCategory extends RowModel "description" => "Sample Text", ]); } - - function getSlug(): string + + public function getSlug(): string { return str_replace("ʹ", "-", Transliterator::createFromRules( ":: Any-Latin;" @@ -41,116 +46,123 @@ class GiftCategory extends RowModel . "[:Separator:] > '-'" )->transliterate($this->getName())); } - - function getThumbnailURL(): string + + public function getThumbnailURL(): string { $primeGift = iterator_to_array($this->getGifts(1, 1))[0]; $serverUrl = ovk_scheme(true) . $_SERVER["SERVER_NAME"]; - if(!$primeGift) + if (!$primeGift) { return "$serverUrl/assets/packages/static/openvk/img/camera_200.png"; - + } + 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(); - if(!$loc) { - if($returnNull) - return NULL; - + if (!$loc) { + if ($returnNull) { + return null; + } + return $language === "_" ? "Unlocalized" : $this->getName(); } - + 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(); - if(!$loc) { - if($returnNull) - return NULL; - + if (!$loc) { + if ($returnNull) { + return null; + } + return $language === "_" ? "Unlocalized" : $this->getDescription(); } - + 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"); - if($page !== -1) { + if ($page !== -1) { $count = $gifts->count(); $gifts = $gifts->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE); } - - foreach($gifts as $rel) - yield (new Gifts)->get($rel->gift); + + foreach ($gifts as $rel) { + yield (new Gifts())->get($rel->gift); + } } - - function isMagical(): bool + + public function isMagical(): bool { return !is_null($this->getRecord()->autoquery); } - - function hasGift(Gift $gift): bool + + public function hasGift(Gift $gift): bool { $rels = $this->getRecord()->related("gift_relations.category"); - + 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; - + } + DB::i()->getContext()->table("gift_relations")->insert([ "category" => $this->getId(), "gift" => $gift->getId(), ]); } - - function removeGift(Gift $gift): void + + public function removeGift(Gift $gift): void { - if(!$this->hasGift($gift)) + if (!$this->hasGift($gift)) { return; - + } + DB::i()->getContext()->table("gift_relations")->where([ "category" => $this->getId(), "gift" => $gift->getId(), ])->delete(); } - - function setName(string $language, string $name): void + + public function setName(string $language, string $name): void { $this->createLocalizationIfNotExists($language); $this->getLocalization($language)->update([ "name" => $name, ]); } - - function setDescription(string $language, string $description): void + + public function setDescription(string $language, string $description): void { $this->createLocalizationIfNotExists($language); $this->getLocalization($language)->update([ "description" => $description, ]); } - - function setAutoQuery(?array $query = NULL): void + + public function setAutoQuery(?array $query = null): void { - if(is_null($query)) { - $this->stateChanges("autoquery", NULL); + if (is_null($query)) { + $this->stateChanges("autoquery", null); return; } - + $allowedColumns = ["price", "usages"]; - if(array_diff_key($query, array_flip($allowedColumns))) + if (array_diff_key($query, array_flip($allowedColumns))) { throw new \LogicException("Invalid query"); - + } + $this->stateChanges("autoquery", serialize($query)); } } diff --git a/Web/Models/Entities/IP.php b/Web/Models/Entities/IP.php index 0d9b8fd0..4f3b6595 100644 --- a/Web/Models/Entities/IP.php +++ b/Web/Models/Entities/IP.php @@ -1,45 +1,49 @@ -getRecord()->ip); } - - function getDiscoveryDate(): DateTime + + public function getDiscoveryDate(): DateTime { return new DateTime($this->getRecord()->first_seen); } - - function isBanned(): bool + + public function isBanned(): bool { return (bool) $this->getRecord()->banned; } - - function ban(): void + + public function ban(): void { $this->stateChanges("banned", true); $this->save(); } - - function pardon(): void + + public function pardon(): void { $this->stateChanges("banned", false); $this->save(); } - - function clear(): void + + public function clear(): void { $this->stateChanges("rate_limit_counter_start", 0); $this->stateChanges("rate_limit_counter", 0); @@ -47,45 +51,45 @@ class IP extends RowModel $this->stateChanges("rate_limit_violation_counter", 0); $this->save(); } - - function rateLimit(int $actionComplexity = 1): int + + public function rateLimit(int $actionComplexity = 1): int { $counterSessionStart = $this->getRecord()->rate_limit_counter_start; $vCounterSessionStart = $this->getRecord()->rate_limit_violation_counter_start; - + $aCounter = $this->getRecord()->rate_limit_counter; $vCounter = $this->getRecord()->rate_limit_violation_counter; - + $config = (object) OPENVK_ROOT_CONF["openvk"]["preferences"]["security"]["rateLimits"]; - + try { - if((time() - $config->time) > $counterSessionStart) { + if ((time() - $config->time) > $counterSessionStart) { $counterSessionStart = time(); $aCounter = $actionComplexity; - + return static::RL_RESET; } - - if(($aCounter + $actionComplexity) <= $config->actions) { + + if (($aCounter + $actionComplexity) <= $config->actions) { $aCounter += $actionComplexity; - + return static::RL_CANEXEC; } - - if((time() - $config->maxViolationsAge) > $vCounterSessionStart) { + + if ((time() - $config->maxViolationsAge) > $vCounterSessionStart) { $vCounterSessionStart = time(); $vCounter = 1; - + return static::RL_VIOLATION; } - + $vCounter += 1; - if($vCounter >= $config->maxViolations) { + if ($vCounter >= $config->maxViolations) { $this->stateChanges("banned", true); - + return static::RL_BANNED; } - + return static::RL_VIOLATION; } finally { $this->stateChanges("rate_limit_counter_start", $counterSessionStart); @@ -95,21 +99,23 @@ class IP extends RowModel $this->save(false); } } - - function setIp(string $ip): void + + public function setIp(string $ip): void { $ip = inet_pton($ip); - if(!$ip) + if (!$ip) { throw new \UnexpectedValueException("Malformed IP address"); - + } + $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()); - + } + parent::save($log); } } diff --git a/Web/Models/Entities/Manager.php b/Web/Models/Entities/Manager.php index 0876e01e..279c88a3 100644 --- a/Web/Models/Entities/Manager.php +++ b/Web/Models/Entities/Manager.php @@ -1,5 +1,9 @@ -getRecord()->id; } - - function getUserId(): int + + public function getUserId(): int { 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; } - 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; } - function isHidden(): bool + public function isHidden(): bool { return (bool) $this->getRecord()->hidden; } - function isClubPinned(): bool + public function isClubPinned(): bool { return (bool) $this->getRecord()->club_pinned; } - - use Traits\TSubscribable; } diff --git a/Web/Models/Entities/Media.php b/Web/Models/Entities/Media.php index 648d3564..2fb2248a 100644 --- a/Web/Models/Entities/Media.php +++ b/Web/Models/Entities/Media.php @@ -1,68 +1,77 @@ -changes["hash"])) + if (isset($this->changes["hash"])) { unlink($this->pathFromHash($this->changes["hash"])); + } } - + protected function getBaseDir(): string { $uploadSettings = OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]; - if($uploadSettings["mode"] === "server" && $uploadSettings["server"]["kind"] === "cdn") + if ($uploadSettings["mode"] === "server" && $uploadSettings["server"]["kind"] === "cdn") { return $uploadSettings["server"]["directory"]; - else + } else { return OPENVK_ROOT . "/storage/"; + } } protected function checkIfFileIsProcessed(): bool { throw new \LogicException("checkIfFileIsProcessed is not implemented"); } - + abstract protected function saveFile(string $filename, string $hash): bool; - + protected function pathFromHash(string $hash): string { $dir = $this->getBaseDir() . substr($hash, 0, 2); - if(!is_dir($dir)) + if (!is_dir($dir)) { mkdir($dir); - + } + return "$dir/$hash." . $this->fileExtension; } - - function getFileName(): string + + public function getFileName(): string { return $this->pathFromHash($this->getRecord()->hash); } - - function getURL(): string + + public function getURL(): string { - if(!is_null($this->processingPlaceholder)) - if(!$this->isProcessed()) + if (!is_null($this->processingPlaceholder)) { + if (!$this->isProcessed()) { return "/assets/packages/static/openvk/$this->processingPlaceholder.$this->fileExtension"; + } + } $hash = $this->getRecord()->hash; - - switch(OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["mode"]) { + + switch (OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["mode"]) { default: case "default": case "basic": return "http://" . $_SERVER['HTTP_HOST'] . "/blob_" . substr($hash, 0, 2) . "/$hash.$this->fileExtension"; - break; + break; case "accelerated": return "http://" . $_SERVER['HTTP_HOST'] . "/openvk-datastore/$hash.$this->fileExtension"; - break; + break; case "server": $settings = (object) OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["server"]; return ( @@ -71,26 +80,29 @@ abstract class Media extends Postable $settings->path . substr($hash, 0, 2) . "/$hash.$this->fileExtension" ); - break; + break; } } - - function getDescription(): ?string + + public function getDescription(): ?string { return $this->getRecord()->description; } protected function isProcessed(): bool { - if(is_null($this->processingPlaceholder)) + if (is_null($this->processingPlaceholder)) { return true; + } - if($this->getRecord()->processed) + if ($this->getRecord()->processed) { return true; + } $timeDiff = time() - $this->getRecord()->last_checked; - if($timeDiff < $this->processingTime) + if ($timeDiff < $this->processingTime) { return false; + } $res = $this->checkIfFileIsProcessed(); $this->stateChanges("last_checked", time()); @@ -99,31 +111,32 @@ abstract class Media extends Postable return $res; } - - function isDeleted(): bool + + public function isDeleted(): bool { 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"); } - - 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"); - + } + $hash = hash_file("whirlpool", $file["tmp_name"]); $this->saveFile($file["tmp_name"], $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("last_checked", time()); } @@ -131,20 +144,22 @@ abstract class Media extends Postable parent::save($log); } - function delete(bool $softly = true): void + public function delete(bool $softly = true): void { $deleteQuirk = ovkGetQuirk("blobs.erase-upon-deletion"); - if($deleteQuirk === 2 || ($deleteQuirk === 1 && !$softly)) + if ($deleteQuirk === 2 || ($deleteQuirk === 1 && !$softly)) { @unlink($this->getFileName()); - + } + 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)"); - + } + parent::undelete(); } } diff --git a/Web/Models/Entities/MediaCollection.php b/Web/Models/Entities/MediaCollection.php index 1f061988..f3f340b4 100644 --- a/Web/Models/Entities/MediaCollection.php +++ b/Web/Models/Entities/MediaCollection.php @@ -1,5 +1,9 @@ -relations = DatabaseConnection::i()->getContext()->table($this->relTableName); } - + 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')."); - + } + return true; } - - function getOwner(): RowModel + + public function getOwner(): RowModel { $oid = $this->getRecord()->owner; - if($oid > 0) - return (new Users)->get($oid); - else - return (new Clubs)->get($oid * -1); + if ($oid > 0) { + return (new Users())->get($oid); + } else { + return (new Clubs())->get($oid * -1); + } } - - function getPrettyId(): string + + public function getPrettyId(): string { return $this->getRecord()->owner . "_" . $this->getRecord()->id; } - - function getName(): string + + public function getName(): string { $special = $this->getRecord()->special_type; - if($special === 0) + if ($special === 0) { return $this->getRecord()->name; - + } + $sName = $this->specialNames[$special]; - if(!$sName) + if (!$sName) { return $this->getRecord()->name; - - if($sName[0] === "_") + } + + if ($sName[0] === "_") { $sName = tr(substr($sName, 1)); - + } + return $sName; } - - function getDescription(): ?string + + public function getDescription(): ?string { 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") ->limit($limit ?? OPENVK_DEFAULT_PER_PAGE, $offset) ->order("media ASC"); - foreach($related as $rel) { + foreach ($related as $rel) { $media = $rel->ref($this->entityTableName, "media"); - if(!$media) + if (!$media) { continue; + } 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); $perPage ??= OPENVK_DEFAULT_PER_PAGE; return $this->fetchClassic($perPage * ($page - 1), $perPage); } - - function size(): int + + public function size(): int { return sizeof($this->getRecord()->related("$this->relTableName.collection")); } - - function getCreationTime(): DateTime + + public function getCreationTime(): DateTime { return new DateTime($this->getRecord()->created); } - - function getPublicationTime(): DateTime + + public function getPublicationTime(): DateTime { return $this->getCreationTime(); } - - function getEditTime(): ?DateTime + + public function getEditTime(): ?DateTime { $edited = $this->getRecord()->edited; - if(is_null($edited)) return NULL; - + if (is_null($edited)) { + return null; + } + return new DateTime($edited); } - - function isCreatedBySystem(): bool + + public function isCreatedBySystem(): bool { return $this->getRecord()->special_type !== 0; } - function add(RowModel $entity): bool + public function add(RowModel $entity): bool { $this->entitySuitable($entity); - - if(!$this->allowDuplicates) - if($this->has($entity)) - return false; - if(self::MAX_ITEMS != INF) - if(sizeof($this->relations->where("collection", $this->getId())) > self::MAX_ITEMS) + if (!$this->allowDuplicates) { + 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"); - + } + } + $this->relations->insert([ "collection" => $this->getId(), "media" => $entity->getId(), ]); - + return true; } - - function remove(RowModel $entity): bool + + public function remove(RowModel $entity): bool { $this->entitySuitable($entity); - + return $this->relations->where([ "collection" => $this->getId(), "media" => $entity->getId(), ])->delete() > 0; } - - function has(RowModel $entity): bool + + public function has(RowModel $entity): bool { $this->entitySuitable($entity); - + $rel = $this->relations->where([ "collection" => $this->getId(), "media" => $entity->getId(), ])->fetch(); - + return !is_null($rel); } - function save(?bool $log = false): void + public function save(?bool $log = false): void { $thisTable = DatabaseConnection::i()->getContext()->table($this->tableName); - if(self::MAX_COUNT != INF) - if(isset($this->changes["owner"])) - if(sizeof($thisTable->where("owner", $this->changes["owner"])) > self::MAX_COUNT) + if (self::MAX_COUNT != INF) { + if (isset($this->changes["owner"])) { + if (sizeof($thisTable->where("owner", $this->changes["owner"])) > self::MAX_COUNT) { throw new \OutOfBoundsException("Maximum amount of collections"); + } + } + } - if(is_null($this->getRecord())) - if(!isset($this->changes["created"])) + if (is_null($this->getRecord())) { + if (!isset($this->changes["created"])) { $this->stateChanges("created", time()); - else - $this->stateChanges("edited", time()); + } else { + $this->stateChanges("edited", time()); + } + } 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()) ->delete(); } parent::delete($softly); } - - use Traits\TOwnable; } diff --git a/Web/Models/Entities/Message.php b/Web/Models/Entities/Message.php index 29e6578e..4e9b8455 100644 --- a/Web/Models/Entities/Message.php +++ b/Web/Models/Entities/Message.php @@ -1,5 +1,9 @@ -getRecord()->sender_type === 'openvk\Web\Models\Entities\User') - return (new Users)->get($this->getRecord()->sender_id); - else if($this->getRecord()->sender_type === 'openvk\Web\Models\Entities\Club') - return (new Clubs)->get($this->getRecord()->sender_id); + if ($this->getRecord()->sender_type === 'openvk\Web\Models\Entities\User') { + return (new Users())->get($this->getRecord()->sender_id); + } elseif ($this->getRecord()->sender_type === 'openvk\Web\Models\Entities\Club') { + return (new Clubs())->get($this->getRecord()->sender_id); + } } - + /** * Get the destination of the message. - * + * * Returns either user or club. - * + * * @returns User|Club */ - function getRecipient(): ?RowModel + public function getRecipient(): ?RowModel { - if($this->getRecord()->recipient_type === 'openvk\Web\Models\Entities\User') - return (new Users)->get($this->getRecord()->recipient_id); - else if($this->getRecord()->recipient_type === 'openvk\Web\Models\Entities\Club') - return (new Clubs)->get($this->getRecord()->recipient_id); + if ($this->getRecord()->recipient_type === 'openvk\Web\Models\Entities\User') { + return (new Users())->get($this->getRecord()->recipient_id); + } elseif ($this->getRecord()->recipient_type === 'openvk\Web\Models\Entities\Club') { + return (new Clubs())->get($this->getRecord()->recipient_id); + } } - - function getUnreadState(): int + + public function getUnreadState(): int { trigger_error("TODO: use isUnread", E_USER_DEPRECATED); - + return (int) $this->isUnread(); } - + /** * Get date of initial publication. - * + * * @returns DateTime */ - function getSendTime(): DateTime + public function getSendTime(): DateTime { return new DateTime($this->getRecord()->created); } - function getSendTimeHumanized(): string + public function getSendTimeHumanized(): string { $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"); } else { return $dateTime->format("%d.%m.%y"); } } - + /** * Get date of last edit, if any edits were made, otherwise null. - * + * * @returns DateTime|null */ - function getEditTime(): ?DateTime + public function getEditTime(): ?DateTime { $edited = $this->getRecord()->edited; - if(is_null($edited)) return NULL; - + if (is_null($edited)) { + return null; + } + return new DateTime($edited); } - + /** * Is this message an ad? - * + * * Messages can never be ads. - * + * * @returns false */ - function isAd(): bool + public function isAd(): bool { return false; } - - function isUnread(): bool + + public function isUnread(): bool { return (bool) $this->getRecord()->unread; } - + /** * Simplify to array - * + * * @returns array */ - function simplify(): array + public function simplify(): array { $author = $this->getSender(); - + $attachments = []; - foreach($this->getChildren() as $attachment) { - if($attachment instanceof Photo) { + foreach ($this->getChildren() as $attachment) { + if ($attachment instanceof Photo) { $attachments[] = [ "type" => "photo", "link" => "/photo" . $attachment->getPrettyId(), @@ -124,31 +134,28 @@ class Message extends RowModel ]; } else { $attachments[] = [ - "type" => "unknown" + "type" => "unknown", ]; - + # throw new \Exception("Unknown attachment type: " . get_class($attachment)); } } - + return [ "uuid" => $this->getId(), "sender" => [ "id" => $author->getId(), "link" => $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $author->getURL(), "avatar" => $author->getAvatarUrl(), - "name" => $author->getFirstName().$unreadmsg, + "name" => $author->getFirstName() . $unreadmsg, ], "timing" => [ "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(), "read" => !$this->isUnread(), "attachments" => $attachments, ]; } - - use Traits\TRichText; - use Traits\TAttachmentHost; } diff --git a/Web/Models/Entities/NoSpamLog.php b/Web/Models/Entities/NoSpamLog.php index 48d723c9..a44452ce 100644 --- a/Web/Models/Entities/NoSpamLog.php +++ b/Web/Models/Entities/NoSpamLog.php @@ -1,5 +1,9 @@ -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; } - function getRegex(): ?string + public function getRegex(): ?string { return $this->getRecord()->regex; } - function getRequest(): ?string + public function getRequest(): ?string { return $this->getRecord()->request; } - function getCount(): int + public function getCount(): int { return $this->getRecord()->count; } - function getTime(): DateTime + public function getTime(): DateTime { return new DateTime($this->getRecord()->time); } - function getItems(): ?array + public function getItems(): ?array { return explode(",", $this->getRecord()->items); } - function getTypeRaw(): int + public function getTypeRaw(): int { return $this->getRecord()->ban_type; } - function getType(): string + public function getType(): string { switch ($this->getTypeRaw()) { case 1: return "О"; @@ -64,7 +68,7 @@ class NoSpamLog extends RowModel } } - function isRollbacked(): bool + public function isRollbacked(): bool { return !is_null($this->getRecord()->rollback); } diff --git a/Web/Models/Entities/Note.php b/Web/Models/Entities/Note.php index 33ac6b04..17898a10 100644 --- a/Web/Models/Entities/Note.php +++ b/Web/Models/Entities/Note.php @@ -1,12 +1,16 @@ -set("Attr.AllowedClasses", [ "underline", ]); - - $source = NULL; - if(is_null($this->getRecord())) { - if(isset($this->changes["source"])) + + $source = null; + if (is_null($this->getRecord())) { + if (isset($this->changes["source"])) { $source = $this->changes["source"]; - else + } else { throw new \LogicException("Can't render note without content set."); + } } else { $source = $this->getRecord()->source; } - + $purifier = new HTMLPurifier($config); return $purifier->purify($source); } - - function getName(): string + + public function getName(): string { 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); } - - function getText(): string + + public function getText(): string { - if(is_null($this->getRecord())) + if (is_null($this->getRecord())) { return $this->renderHTML(); - + } + $cached = $this->getRecord()->cached_content; - if(!$cached) { + if (!$cached) { $cached = $this->renderHTML(); $this->setCached_Content($cached); $this->save(); } - + return $cached; } - function getSource(): string + public function getSource(): string { 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 $this->getOwner()->getPrivacyPermission('notes.read', $user) && $this->getOwner()->canBeViewedBy($user); } - function toVkApiStruct(): object + public function toVkApiStruct(): object { $res = (object) []; @@ -140,7 +146,7 @@ class Note extends Postable $res->date = $this->getPublicationTime()->timestamp(); $res->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->can_comment = 1; $res->text_wiki = "r"; diff --git a/Web/Models/Entities/Notifications/ClubModeratorNotification.php b/Web/Models/Entities/Notifications/ClubModeratorNotification.php index cb89deea..28563b69 100644 --- a/Web/Models/Entities/Notifications/ClubModeratorNotification.php +++ b/Web/Models/Entities/Notifications/ClubModeratorNotification.php @@ -1,12 +1,16 @@ -getText()), 400)); } diff --git a/Web/Models/Entities/Notifications/FriendRemovalNotification.php b/Web/Models/Entities/Notifications/FriendRemovalNotification.php index 17d68e0a..d7cbcb26 100644 --- a/Web/Models/Entities/Notifications/FriendRemovalNotification.php +++ b/Web/Models/Entities/Notifications/FriendRemovalNotification.php @@ -1,12 +1,16 @@ -recipient = $recipient; $this->originModel = $originModel; @@ -24,67 +28,68 @@ class Notification $this->time = $time ?? time(); $this->data = $data; } - + private function encodeType(object $model): int { return (int) json_decode(file_get_contents(__DIR__ . "/../../../../data/modelCodes.json"), true)[get_class($model)]; } - - function reverseModelOrder(): bool + + public function reverseModelOrder(): bool { return false; } - - function getActionCode(): int + + public function getActionCode(): int { 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("_", [ "./../components/notifications/$this->actionCode/", $this->encodeType($this->originModel), $this->encodeType($this->targetModel), - ".xml" + ".xml", ]); } - - function getRecipient(): User + + public function getRecipient(): User { return $this->recipient; } - - function getModel(int $index): RowModel + + public function getModel(int $index): RowModel { - switch($index) { + switch ($index) { case 0: return $this->originModel; case 1: return $this->targetModel; } } - - function getData(): string + + public function getData(): string { return $this->data; } - - function getDateTime(): DateTime + + public function getDateTime(): DateTime { return new DateTime($this->time); } - - function emit(): bool + + public function emit(): bool { - if(!($e = eventdb())) + if (!($e = eventdb())) { return false; - + } + $data = [ "recipient" => $this->recipient->getId(), "originModelType" => $this->encodeType($this->originModel), @@ -95,56 +100,57 @@ class Notification "additionalPayload" => $this->data, "timestamp" => $this->time, ]; - + $edb = $e->getConnection(); - if($this->threshold !== -1) { + if ($this->threshold !== -1) { # Event is thersholded, check if there is similar event $query = <<<'QUERY' - SELECT * FROM `notifications` WHERE `recipientType`=0 AND `recipientId`=? AND `originModelType`=? AND `originModelId`=? AND `targetModelType`=? AND `targetModelId`=? AND `modelAction`=? AND `additionalData`=? AND `timestamp` > (? - ?) -QUERY; + SELECT * FROM `notifications` WHERE `recipientType`=0 AND `recipientId`=? AND `originModelType`=? AND `originModelId`=? AND `targetModelType`=? AND `targetModelId`=? AND `modelAction`=? AND `additionalData`=? AND `timestamp` > (? - ?) + QUERY; $result = $edb->query($query, ...array_merge(array_values($data), [ $this->threshold ])); - if($result->getRowCount() > 0) + if ($result->getRowCount() > 0) { return false; + } } - + $edb->query("INSERT INTO notifications VALUES (0, ?, ?, ?, ?, ?, ?, ?, ?)", ...array_values($data)); - + $kafkaConf = OPENVK_ROOT_CONF["openvk"]["credentials"]["notificationsBroker"]; - if($kafkaConf["enable"]) { + if ($kafkaConf["enable"]) { $kafkaConf = $kafkaConf["kafka"]; $brokerConf = new Conf(); $brokerConf->set("log_level", (string) LOG_DEBUG); $brokerConf->set("debug", "all"); - + $producer = new Producer($brokerConf); $producer->addBrokers($kafkaConf["addr"] . ":" . $kafkaConf["port"]); - + $descriptor = implode(",", [ str_replace("\\", ".", get_class($this)), $this->recipient->getId(), base64_encode(serialize((object) $data)), ]); - + $notifTopic = $producer->newTopic($kafkaConf["topic"]); $notifTopic->produce(RD_KAFKA_PARTITION_UA, RD_KAFKA_MSG_F_BLOCK, $descriptor); $producer->flush(100); } - + return true; } - function getVkApiInfo() + public function getVkApiInfo() { $origin_m = $this->encodeType($this->originModel); $target_m = $this->encodeType($this->targetModel); $info = [ "type" => "", - "parent" => NULL, - "feedback" => NULL, + "parent" => null, + "feedback" => null, ]; - switch($this->getActionCode()) { + switch ($this->getActionCode()) { case 0: $info["type"] = "like_post"; $info["parent"] = $this->getModel(0)->toNotifApiStruct(); @@ -153,32 +159,32 @@ QUERY; case 1: $info["type"] = "copy_post"; $info["parent"] = $this->getModel(0)->toNotifApiStruct(); - $info["feedback"] = NULL; # todo + $info["feedback"] = null; # todo break; case 2: - switch($origin_m) { + switch ($origin_m) { case 19: $info["type"] = "comment_video"; $info["parent"] = $this->getModel(0)->toNotifApiStruct(); - $info["feedback"] = NULL; # айди коммента не сохраняется в бд( ну пиздец блять + $info["feedback"] = null; # айди коммента не сохраняется в бд( ну пиздец блять break; case 13: $info["type"] = "comment_photo"; $info["parent"] = $this->getModel(0)->toNotifApiStruct(); - $info["feedback"] = NULL; + $info["feedback"] = null; break; - # unstandart (vk forgor about notes) + # unstandart (vk forgor about notes) case 10: $info["type"] = "comment_note"; $info["parent"] = $this->getModel(0)->toVkApiStruct(); - $info["feedback"] = NULL; + $info["feedback"] = null; break; case 14: $info["type"] = "comment_post"; $info["parent"] = $this->getModel(0)->toNotifApiStruct(); - $info["feedback"] = NULL; + $info["feedback"] = null; break; - # unused (users don't have topics bruh) + # unused (users don't have topics bruh) case 21: $info["type"] = "comment_topic"; $info["parent"] = $this->getModel(0)->toVkApiStruct(0, 90); @@ -194,7 +200,7 @@ QUERY; $info["feedback"] = $this->getModel(0)->toNotifApiStruct(); break; case 4: - switch($target_m) { + switch ($target_m) { case 14: $info["type"] = "mention"; $info["feedback"] = $this->getModel(1)->toNotifApiStruct(); @@ -207,7 +213,7 @@ QUERY; $info["type"] = "mention_comment_photo"; $info["parent"] = $this->getModel(1)->toNotifApiStruct(); break; - # unstandart + # unstandart case 10: $info["type"] = "mention_comment_note"; $info["parent"] = $this->getModel(1)->toVkApiStruct(); @@ -224,15 +230,15 @@ QUERY; $info["type"] = "make_you_admin"; $info["parent"] = $this->getModel(0)->toVkApiStruct($this->getModel(1)); break; - # Нужно доделать после мержа #935 + # Нужно доделать после мержа #935 case 6: $info["type"] = "wall_publish"; break; - # В вк не было такого уведомления, так что unstandart + # В вк не было такого уведомления, так что unstandart case 7: $info["type"] = "new_posts_in_club"; break; - # В вк при передаче подарков приходит сообщение, а не уведомление, так что unstandart + # В вк при передаче подарков приходит сообщение, а не уведомление, так что unstandart case 9601: $info["type"] = "sent_gift"; $info["parent"] = $this->getModel(1)->toVkApiStruct($this->getModel(1)); @@ -247,23 +253,23 @@ QUERY; $info["parent"]->count = $this->getData(); break; default: - $info["type"] = NULL; + $info["type"] = null; break; } return $info; } - function toVkApiStruct() + public function toVkApiStruct() { - $res = (object)[]; + $res = (object) []; $info = $this->getVkApiInfo(); $res->type = $info["type"]; $res->date = $this->getDateTime()->timestamp(); $res->parent = $info["parent"]; $res->feedback = $info["feedback"]; - $res->reply = NULL; # Ответы на комментарии не реализованы + $res->reply = null; # Ответы на комментарии не реализованы return $res; } } diff --git a/Web/Models/Entities/Notifications/PostAcceptedNotification.php b/Web/Models/Entities/Notifications/PostAcceptedNotification.php index bb99d34e..2f456d8e 100644 --- a/Web/Models/Entities/Notifications/PostAcceptedNotification.php +++ b/Web/Models/Entities/Notifications/PostAcceptedNotification.php @@ -1,12 +1,16 @@ -getText(), 10)); } diff --git a/Web/Models/Entities/PasswordReset.php b/Web/Models/Entities/PasswordReset.php index 372c63f8..6073f183 100644 --- a/Web/Models/Entities/PasswordReset.php +++ b/Web/Models/Entities/PasswordReset.php @@ -1,5 +1,9 @@ -get($this->getRecord()->profile); + return (new Users())->get($this->getRecord()->profile); } - - function getKey(): string + + public function getKey(): string { return $this->getRecord()->key; } - - function getToken(): string + + public function getToken(): string { return $this->getKey(); } - - function getCreationTime(): DateTime + + public function getCreationTime(): DateTime { return new DateTime($this->getRecord()->timestamp); } - + /** * 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. */ - function isNew(): bool + public function isNew(): bool { return $this->getRecord()->timestamp > (time() - (5 * MINUTE)); } - + /** * Token is valid only for 3 days. */ - function isStillValid(): bool + public function isStillValid(): bool { return $this->getRecord()->timestamp > (time() - (3 * DAY)); } - - function verify(string $token): bool + + public function verify(string $token): bool { try { return $this->isStillValid() ? sodium_memcmp($this->getKey(), $token) : false; - } catch(\SodiumException $ex) { + } catch (\SodiumException $ex) { 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("timestamp", time()); - + parent::save($log); } } diff --git a/Web/Models/Entities/Photo.php b/Web/Models/Entities/Photo.php index bd0e65cc..1eb42110 100644 --- a/Web/Models/Entities/Photo.php +++ b/Web/Models/Entities/Photo.php @@ -1,5 +1,9 @@ -getImageWidth() / $image->getImageHeight()) > ($px / $py)) { + if (($image->getImageWidth() / $image->getImageHeight()) > ($px / $py)) { $height = (int) ceil(($px * $image->getImageWidth()) / $py); $image->cropImage($image->getImageWidth(), $height, 0, 0); $res[0] = true; } } - - if(isset($size["maxSize"])) { + + if (isset($size["maxSize"])) { $maxSize = (int) $size["maxSize"]; $sizes = Image::calculateSize($image->getImageWidth(), $image->getImageHeight(), $maxSize, $maxSize, Image::SHRINK_ONLY | Image::FIT); $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"]); $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); } else { throw new \RuntimeException("Malformed size description: " . (string) $size["id"]); } - + $res[1] = $image->getImageWidth(); $res[2] = $image->getImageHeight(); - if($res[1] <= 300 || $res[2] <= 300) + if ($res[1] <= 300 || $res[2] <= 300) { $image->writeImage("$outputDir/$size[id].gif"); - else + } else { $image->writeImage("$outputDir/$size[id].jpeg"); - + } + $res[3] = true; $image->destroy(); unset($image); - + return $res; } private function saveImageResizedCopies(?\Imagick $image, string $filename, string $hash): void { - if(!$image) { - $image = new \Imagick; + if (!$image) { + $image = new \Imagick(); $image->readImage($filename); } - + $dir = dirname($this->pathFromHash($hash)); $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) mkdir($dir); } $sizes = simplexml_load_file(OPENVK_ROOT . "/data/photosizes.xml"); - if(!$sizes) + if (!$sizes) { throw new \RuntimeException("Could not load photosizes.xml!"); + } $sizesMeta = []; - if(OPENVK_ROOT_CONF["openvk"]["preferences"]["photos"]["photoSaving"] === "quick") { - foreach($sizes->Size as $size) - $sizesMeta[(string)$size["id"]] = [false, false, false, false]; + if (OPENVK_ROOT_CONF["openvk"]["preferences"]["photos"]["photoSaving"] === "quick") { + foreach ($sizes->Size as $size) { + $sizesMeta[(string) $size["id"]] = [false, false, false, false]; + } } else { - foreach($sizes->Size as $size) - $sizesMeta[(string)$size["id"]] = $this->resizeImage(clone $image, $dir, $size); + foreach ($sizes->Size as $size) { + $sizesMeta[(string) $size["id"]] = $this->resizeImage(clone $image, $dir, $size); + } } $sizesMeta = MessagePack::pack($sizesMeta); @@ -97,16 +109,18 @@ class Photo extends Media protected function saveFile(string $filename, string $hash): bool { - $input_image = new \Imagick; + $input_image = new \Imagick(); $input_image->readImage($filename); $h = $input_image->getImageHeight(); $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"); - + } + # gif fix 10.01.2025 - if($input_image->getImageFormat() === 'GIF') + if ($input_image->getImageFormat() === 'GIF') { $input_image->setIteratorIndex(0); + } # png workaround (transparency to white) $image = new \Imagick(); @@ -115,66 +129,72 @@ class Photo extends Media $image->compositeImage($input_image, \Imagick::COMPOSITE_OVER, 0, 0); $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->writeImage($this->pathFromHash($hash)); $this->saveImageResizedCopies($image, $filename, $hash); - + 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"]; - else if(!is_null($this->getRecord())) + } elseif (!is_null($this->getRecord())) { $hash = $this->getRecord()->hash; - else + } else { throw new ISE("Cannot crop uninitialized image. Please call setFile(\$_FILES[...]) first."); - + } + $image = Image::fromFile($this->pathFromHash($hash)); $image->crop($left, $top, $width, $height); $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."); - + } + 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; - if(!$sizes || $forceUpdate) { - if($forceUpdate || $upgrade || OPENVK_ROOT_CONF["openvk"]["preferences"]["photos"]["upgradeStructure"]) { + if (!$sizes || $forceUpdate) { + if ($forceUpdate || $upgrade || OPENVK_ROOT_CONF["openvk"]["preferences"]["photos"]["upgradeStructure"]) { $hash = $this->getRecord()->hash; - $this->saveImageResizedCopies(NULL, $this->pathFromHash($hash), $hash); + $this->saveImageResizedCopies(null, $this->pathFromHash($hash), $hash); $this->save(); return $this->getSizes(); } - return NULL; + return null; } $res = []; $sizes = MessagePack::unpack($sizes); - foreach($sizes as $id => $meta) { - if(isset($meta[3]) && !$meta[3]) { + foreach ($sizes as $id => $meta) { + if (isset($meta[3]) && !$meta[3]) { $res[$id] = (object) [ "url" => ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/photos/thumbnails/" . $this->getId() . "_$id.jpeg", - "width" => NULL, - "height" => NULL, - "crop" => NULL + "width" => null, + "height" => null, + "crop" => null, ]; continue; } - + $url = $this->getURL(); $url = str_replace(".$this->fileExtension", "_cropped/$id.", $url); $url .= ($meta[1] <= 300 || $meta[2] <= 300) ? "gif" : "jpeg"; @@ -183,7 +203,7 @@ class Photo extends Media "url" => $url, "width" => $meta[1], "height" => $meta[2], - "crop" => $meta[0] + "crop" => $meta[0], ]; } @@ -192,69 +212,78 @@ class Photo extends Media "url" => $this->getURL(), "width" => $x, "height" => $y, - "crop" => false + "crop" => false, ]; return $res; } - - function forceSize(string $sizeName): bool + + public function forceSize(string $sizeName): bool { $hash = $this->getRecord()->hash; $sizes = MessagePack::unpack($this->getRecord()->sizes); $size = $sizes[$sizeName] ?? false; - if(!$size) + if (!$size) { return $size; - - if(!isset($size[3]) || $size[3] === true) + } + + if (!isset($size[3]) || $size[3] === true) { return true; - + } + $path = $this->pathFromHash($hash); $dir = dirname($this->pathFromHash($hash)); $dir = "$dir/$hash" . "_cropped"; - if(!is_dir($dir)) { + if (!is_dir($dir)) { @unlink($dir); mkdir($dir); } - + $sizeMetas = simplexml_load_file(OPENVK_ROOT . "/data/photosizes.xml"); - if(!$sizeMetas) + if (!$sizeMetas) { throw new \RuntimeException("Could not load photosizes.xml!"); - - $sizeInfo = NULL; - foreach($sizeMetas->Size as $size) - if($size["id"] == $sizeName) + } + + $sizeInfo = null; + foreach ($sizeMetas->Size as $size) { + if ($size["id"] == $sizeName) { $sizeInfo = $size; - - if(!$sizeInfo) + } + } + + if (!$sizeInfo) { return false; - - $pic = new \Imagick; + } + + $pic = new \Imagick(); $pic->readImage($path); $sizes[$sizeName] = $this->resizeImage($pic, $dir, $sizeInfo); - + $this->stateChanges("sizes", MessagePack::pack($sizes)); $this->save(); - + return $sizes[$sizeName][3]; } - function getVkApiSizes(): ?array + public function getVkApiSizes(): ?array { $res = []; $sizes = $this->getSizes(); - if(!$sizes) - return NULL; + if (!$sizes) { + return null; + } $manifest = simplexml_load_file(OPENVK_ROOT . "/data/photosizes.xml"); - if(!$manifest) - return NULL; + if (!$manifest) { + return null; + } $mappings = []; - foreach($manifest->Size as $size) + foreach ($manifest->Size as $size) { $mappings[(string) $size["id"]] = (string) $size["vkId"]; + } - foreach($sizes as $id => $meta) { + foreach ($sizes as $id => $meta) { $type = $mappings[$id] ?? $id; $meta->type = $type; $res[$type] = $meta; @@ -263,24 +292,26 @@ class Photo extends Media return $res; } - function getURLBySizeId(string $size): string + public function getURLBySizeId(string $size): string { $sizes = $this->getSizes(); - if(!$sizes) + if (!$sizes) { return $this->getURL(); + } $size = $sizes[$size]; - if(!$size) + if (!$size) { return $this->getURL(); + } return $size->url; } - function getDimensions(): array + public function getDimensions(): array { $x = $this->getRecord()->width; $y = $this->getRecord()->height; - if(!$x) { # no sizes in database + if (!$x) { # no sizes in database $hash = $this->getRecord()->hash; $image = Image::fromFile($this->pathFromHash($hash)); @@ -294,31 +325,32 @@ class Photo extends Media 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 "/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->id = $res->pid = $this->getVirtualId(); $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->height = $this->getDimensions()[1]; $res->date = $res->created = $this->getPublicationTime()->timestamp(); - if($photo_sizes) { + if ($photo_sizes) { $res->sizes = array_values($this->getVkApiSizes()); $res->src_small = $res->photo_75 = $this->getURLBySizeId("miniscule"); $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"); } - if($extended) { + if ($extended) { $res->likes = $this->getLikesCount(); # их нету но пусть будут $res->comments = $this->getCommentsCount(); $res->tags = 0; @@ -339,23 +371,23 @@ class Photo extends Media 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; } - if(!is_null($this->getAlbum())) { + if (!is_null($this->getAlbum())) { return $this->getAlbum()->canBeViewedBy($user); } else { 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->setDescription(iconv_substr($description, 0, 36) . "..."); $photo->setAnonymous($anon); @@ -363,7 +395,7 @@ class Photo extends Media $photo->setFile($file); $photo->save(); - if(!is_null($album)) { + if (!is_null($album)) { $album->addPhoto($photo); $album->setEdited(time()); $album->save(); @@ -372,10 +404,10 @@ class Photo extends Media return $photo; } - function toNotifApiStruct() + public function toNotifApiStruct() { - $res = (object)[]; - + $res = (object) []; + $res->id = $this->getVirtualId(); $res->owner_id = $this->getOwner()->getId(); $res->aid = 0; diff --git a/Web/Models/Entities/Playlist.php b/Web/Models/Entities/Playlist.php index ac36b4f3..fedb2d98 100644 --- a/Web/Models/Entities/Playlist.php +++ b/Web/Models/Entities/Playlist.php @@ -1,5 +1,9 @@ -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); } - function getLength(): int + public function getLength(): int { 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") ->limit($limit ?? OPENVK_DEFAULT_PER_PAGE, $offset) ->order("index ASC"); - foreach($related as $rel) { + foreach ($related as $rel) { $media = $rel->ref($this->entityTableName, "media"); - if(!$media) + if (!$media) { continue; + } 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) { - foreach ($this->fetchClassic($offset, $limit) as $e) - yield $e; # No, I can't return, it will break with [] + if (!$shuffleSeed) { + foreach ($this->fetchClassic($offset, $limit) as $e) { + yield $e; + } # No, I can't return, it will break with [] return; } $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 = knuth_shuffle($ids, $shuffleSeed); $ids = array_slice($ids, $offset, $limit ?? OPENVK_DEFAULT_PER_PAGE); - foreach($ids as $id) - yield (new Audios)->get($id); + foreach ($ids as $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->save(); } @@ -86,9 +94,9 @@ class Playlist extends MediaCollection 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->save(); } @@ -96,11 +104,12 @@ class Playlist extends MediaCollection return $res; } - function isBookmarkedBy(RowModel $entity): bool + public function isBookmarkedBy(RowModel $entity): bool { $id = $entity->getId(); - if($entity instanceof Club) + if ($entity instanceof Club) { $id *= -1; + } return !is_null($this->importTable->where([ "entity" => $id, @@ -108,17 +117,20 @@ class Playlist extends MediaCollection ])->fetch()); } - function bookmark(RowModel $entity): bool + public function bookmark(RowModel $entity): bool { - if($this->isBookmarkedBy($entity)) + if ($this->isBookmarkedBy($entity)) { return false; + } $id = $entity->getId(); - if($entity instanceof Club) + if ($entity instanceof Club) { $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"); + } $this->importTable->insert([ "entity" => $id, @@ -128,11 +140,12 @@ class Playlist extends MediaCollection return true; } - function unbookmark(RowModel $entity): bool + public function unbookmark(RowModel $entity): bool { $id = $entity->getId(); - if($entity instanceof Club) + if ($entity instanceof Club) { $id *= -1; + } $count = $this->importTable->where([ "entity" => $id, @@ -141,27 +154,28 @@ class Playlist extends MediaCollection return $count > 0; } - - function getDescription(): ?string + + public function getDescription(): ?string { return $this->getRecord()->description; } - function getDescriptionHTML(): ?string + public function getDescriptionHTML(): ?string { return htmlspecialchars($this->getRecord()->description, ENT_DISALLOWED | ENT_XHTML); } - function getListens() + public function getListens() { return $this->getRecord()->listens; } - function toVkApiStruct(?User $user = NULL): object + public function toVkApiStruct(?User $user = null): object { $oid = $this->getOwner()->getId(); - if($this->getOwner() instanceof Club) + if ($this->getOwner() instanceof Club) { $oid *= -1; + } return (object) [ "id" => $this->getId(), @@ -171,7 +185,7 @@ class Playlist extends MediaCollection "size" => $this->size(), "length" => $this->getLength(), "created" => $this->getCreationTime()->timestamp(), - "modified" => $this->getEditTime() ? $this->getEditTime()->timestamp() : NULL, + "modified" => $this->getEditTime() ? $this->getEditTime()->timestamp() : null, "accessible" => $this->canBeViewedBy($user), "editable" => $this->canBeModifiedBy($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"); } - function resetLength(): bool + public function resetLength(): bool { $this->stateChanges("length", 0); return true; } - function delete(bool $softly = true): void + public function delete(bool $softly = true): void { $ctx = DatabaseConnection::i()->getContext(); $ctx->table("playlist_imports")->where("playlist", $this->getId()) @@ -202,44 +216,46 @@ class Playlist extends MediaCollection parent::delete($softly); } - function hasAudio(Audio $audio): bool + public function hasAudio(Audio $audio): bool { $ctx = DatabaseConnection::i()->getContext(); return !is_null($ctx->table("playlist_relations")->where([ "collection" => $this->getId(), - "media" => $audio->getId() + "media" => $audio->getId(), ])->fetch()); } - function getCoverPhotoId(): ?int + public function getCoverPhotoId(): ?int { 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; + } - if($this->getOwner() instanceof User) + if ($this->getOwner() instanceof User) { return $user->getId() == $this->getOwner()->getId(); - else + } else { 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->setDescription("Playlist cover image"); $cover->setFile($file); @@ -251,32 +267,34 @@ class Playlist extends MediaCollection return $cover; } - function getURL(): string + public function getURL(): string { return "/playlist" . $this->getOwner()->getRealId() . "_" . $this->getId(); } - function incrementListens() + public function incrementListens() { $this->stateChanges("listens", ($this->getListens() + 1)); } - function getMetaDescription(): string + public function getMetaDescription(): string { $length = $this->getLengthInMinutes(); $props = []; $props[] = tr("audios_count", $this->size()); $props[] = "" . tr("listens_count", $this->getListens()) . ""; - if($length > 0) $props[] = tr("minutes_count", $length); + if ($length > 0) { + $props[] = tr("minutes_count", $length); + } $props[] = tr("created_playlist") . " " . $this->getPublicationTime(); # if($this->getEditTime()) $props[] = tr("updated_playlist") . " " . $this->getEditTime(); - + return implode(" • ", $props); } - function isUnlisted(): bool + public function isUnlisted(): bool { - return (bool)$this->getRecord()->unlisted; + return (bool) $this->getRecord()->unlisted; } } diff --git a/Web/Models/Entities/Poll.php b/Web/Models/Entities/Poll.php index 60a39bc5..565e6cce 100644 --- a/Web/Models/Entities/Poll.php +++ b/Web/Models/Entities/Poll.php @@ -1,8 +1,12 @@ -getRecord()->title; } - - function getMetaDescription(): string + + public function getMetaDescription(): string { $props = []; $props[] = tr($this->isAnonymous() ? "poll_anon" : "poll_public"); - if($this->isMultipleChoice()) $props[] = tr("poll_multi"); - if(!$this->isRevotable()) $props[] = tr("poll_lock"); - if(!is_null($this->endsAt())) $props[] = tr("poll_until", $this->endsAt()); - + if ($this->isMultipleChoice()) { + $props[] = tr("poll_multi"); + } + if (!$this->isRevotable()) { + $props[] = tr("poll_lock"); + } + if (!is_null($this->endsAt())) { + $props[] = tr("poll_until", $this->endsAt()); + } + 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"); $res = []; - foreach($options as $opt) + foreach ($options as $opt) { $res[$opt->id] = $opt->name; - + } + return $res; } - - function getUserVote(User $user): ?array + + public function getUserVote(User $user): ?array { $ctx = DatabaseConnection::i()->getContext(); $votedOpts = $ctx->table("poll_votes") ->where(["user" => $user->getId(), "poll" => $this->getId()]); - - if($votedOpts->count() == 0) - return NULL; - + + if ($votedOpts->count() == 0) { + return null; + } + $res = []; - foreach($votedOpts as $votedOpt) { + foreach ($votedOpts as $votedOpt) { $option = $ctx->table("poll_options")->get($votedOpt->option); $res[] = [$option->id, $option->name]; } - + 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 = []; $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]); - foreach($voters->page($page, $perPage) as $vote) - $res[] = (new Users)->get($vote->user); - + foreach ($voters->page($page, $perPage) as $vote) { + $res[] = (new Users())->get($vote->user); + } + return $res; } - - function getVoterCount(?int $optionId = NULL): int + + public function getVoterCount(?int $optionId = null): int { $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->where(["poll" => $this->getId(), "option" => $optionId])->count(); } - - function getResults(?User $user = NULL): object + + public function getResults(?User $user = null): object { $ctx = DatabaseConnection::i()->getContext(); - $voted = NULL; - if(!is_null($user)) + $voted = null; + if (!is_null($user)) { $voted = $this->getUserVote($user); - + } + $result = (object) []; $result->totalVotes = $this->getVoterCount(); - + $unsOptions = []; - foreach($this->getOptions() as $id => $title) { + foreach ($this->getOptions() as $id => $title) { $option = (object) []; $option->id = $id; $option->name = $title; - + $option->votes = $this->getVoterCount($id); $option->pct = $result->totalVotes == 0 ? 0 : min(100, floor(($option->votes / $result->totalVotes) * 100)); $option->voters = $this->getVoters($id, 1, 10); - if(!$user || !$voted) - $option->voted = NULL; - else + if (!$user || !$voted) { + $option->voted = null; + } else { $option->voted = in_array([$id, $title], $voted); - + } + $unsOptions[$id] = $option; } - + $optionsC = sizeof($unsOptions); $sOptions = $unsOptions; - usort($sOptions, function($a, $b) { return $a->votes <=> $b->votes; }); - for($i = 0; $i < $optionsC; $i++) + usort($sOptions, function ($a, $b) { return $a->votes <=> $b->votes; }); + for ($i = 0; $i < $optionsC; $i++) { $unsOptions[$id]->rate = $optionsC - $i - 1; - + } + $result->options = array_values($unsOptions); - + return $result; } - - function isAnonymous(): bool + + public function isAnonymous(): bool { return (bool) $this->getRecord()->is_anonymous; } - - function isMultipleChoice(): bool + + public function isMultipleChoice(): bool { return (bool) $this->getRecord()->allows_multiple; } - - function isRevotable(): bool + + public function isRevotable(): bool { return (bool) $this->getRecord()->can_revote; } - - function endsAt(): ?DateTime + + public function endsAt(): ?DateTime { - if(!$this->getRecord()->until) - return NULL; - + if (!$this->getRecord()->until) { + return null; + } + return new DateTime($this->getRecord()->until); } - - function hasEnded(): bool + + public function hasEnded(): bool { - if($this->getRecord()->ended) + if ($this->getRecord()->ended) { return true; - - if(!is_null($this->getRecord()->until)) + } + + if (!is_null($this->getRecord()->until)) { return time() >= $this->getRecord()->until; - + } + return false; } - - function hasVoted(User $user): bool + + public function hasVoted(User $user): bool { 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; } - - function vote(User $user, array $optionIds): void + + public function vote(User $user, array $optionIds): void { - if($this->hasEnded()) - throw new PollLockedException; - - if($this->hasVoted($user)) - throw new AlreadyVotedException; - - $optionIds = array_map(function($x) { return (int) $x; }, array_unique($optionIds)); + if ($this->hasEnded()) { + throw new PollLockedException(); + } + + if ($this->hasVoted($user)) { + throw new AlreadyVotedException(); + } + + $optionIds = array_map(function ($x) { return (int) $x; }, array_unique($optionIds)); $validOpts = array_keys($this->getOptions()); - if(empty($optionIds) || (sizeof($optionIds) > 1 && !$this->isMultipleChoice())) - throw new UnexpectedValueException; - - if(sizeof(array_diff($optionIds, $validOpts)) > 0) - throw new InvalidOptionException; - - foreach($optionIds as $opt) { + if (empty($optionIds) || (sizeof($optionIds) > 1 && !$this->isMultipleChoice())) { + throw new UnexpectedValueException(); + } + + if (sizeof(array_diff($optionIds, $validOpts)) > 0) { + throw new InvalidOptionException(); + } + + foreach ($optionIds as $opt) { DatabaseConnection::i()->getContext()->table("poll_votes")->insert([ "user" => $user->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()) - throw new PollLockedException; - + if (!$this->isRevotable()) { + throw new PollLockedException(); + } + $this->getRecord()->related("poll_votes.poll") ->where("user", $user->getId())->delete(); } - - function setOwner(User $owner): void + + public function setOwner(User $owner): void { $this->stateChanges("owner", $owner->getId()); } - - function setEndDate(int $timestamp): void + + public function setEndDate(int $timestamp): void { - if(!is_null($this->getRecord())) - throw new PollLockedException; - + if (!is_null($this->getRecord())) { + throw new PollLockedException(); + } + $this->stateChanges("until", $timestamp); } - - function setEnded(): void + + public function setEnded(): void { $this->stateChanges("ended", 1); } - - function setOptions(array $options): void + + public function setOptions(array $options): void { - if(!is_null($this->getRecord())) - throw new PollLockedException; - - if(sizeof($options) > ovkGetQuirk("polls.max-opts")) - throw new TooMuchOptionsException; - + if (!is_null($this->getRecord())) { + throw new PollLockedException(); + } + + if (sizeof($options) > ovkGetQuirk("polls.max-opts")) { + throw new TooMuchOptionsException(); + } + $this->choicesToPersist = $options; } - - function setRevotability(bool $canReVote): void + + public function setRevotability(bool $canReVote): void { - if(!is_null($this->getRecord())) - throw new PollLockedException; - + if (!is_null($this->getRecord())) { + throw new PollLockedException(); + } + $this->stateChanges("can_revote", $canReVote); } - - function setAnonymity(bool $anonymous): void + + public function setAnonymity(bool $anonymous): void { $this->stateChanges("is_anonymous", $anonymous); } - - function setMultipleChoice(bool $mc): void + + public function setMultipleChoice(bool $mc): void { $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); $this->setOwner($owner); @@ -257,46 +286,50 @@ class Poll extends Attachable $this->setMultipleChoice(($xml["multiple"] ?? "no") == "yes"); $this->setAnonymity(($xml["anonymous"] ?? "no") == "yes"); $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"]))); - + } + $options = []; - foreach($xml->options->option as $opt) + foreach ($xml->options->option as $opt) { $options[] = (string) $opt; - - if(empty($options)) - throw new UnexpectedValueException; - + } + + if (empty($options)) { + throw new UnexpectedValueException(); + } + $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->save(); - + return $poll; } - function canBeViewedBy(?User $user = NULL): bool + public function canBeViewedBy(?User $user = null): bool { # waiting for #935 :( /*if(!is_null($this->getAttachedPost())) { return $this->getAttachedPost()->canBeViewedBy($user); } else {*/ - return true; + return true; #} } - - function save(?bool $log = false): void + + public function save(?bool $log = false): void { - if(empty($this->choicesToPersist)) - throw new InvalidStateException; - + if (empty($this->choicesToPersist)) { + throw new InvalidStateException(); + } + parent::save($log); - foreach($this->choicesToPersist as $option) { + foreach ($this->choicesToPersist as $option) { DatabaseConnection::i()->getContext()->table("poll_options")->insert([ "poll" => $this->getId(), "name" => $option, @@ -304,16 +337,18 @@ class Poll extends Attachable } } - function getAttachedPost() + public function getAttachedPost() { $post = DatabaseConnection::i()->getContext()->table("attachments") ->where( - ["attachable_type" => static::class, - "attachable_id" => $this->getId()])->fetch(); + ["attachable_type" => static::class, + "attachable_id" => $this->getId()] + )->fetch(); - if(!is_null($post->target_id)) - return (new Posts)->get($post->target_id); - else - return NULL; + if (!is_null($post->target_id)) { + return (new Posts())->get($post->target_id); + } else { + return null; + } } } diff --git a/Web/Models/Entities/Post.php b/Web/Models/Entities/Post.php index dceaeac9..4079f566 100644 --- a/Web/Models/Entities/Post.php +++ b/Web/Models/Entities/Post.php @@ -1,5 +1,9 @@ - $this->getRecord()->id, ]; - 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 ((sizeof(DB::i()->getContext()->table("likes")->where($searchData)) > 0) !== $liked) { + if ($this->getOwner(false)->getId() !== $user->getId() && !($this->getOwner() instanceof Club) && !$this instanceof Comment) { (new LikeNotification($this->getOwner(false), $this, $user))->emit(); + } parent::setLike($liked, $user); } - if($depth < ovkGetQuirk("wall.repost-liking-recursion-limit")) - foreach($this->getChildren() as $attachment) - if($attachment instanceof Post) + if ($depth < ovkGetQuirk("wall.repost-liking-recursion-limit")) { + foreach ($this->getChildren() as $attachment) { + if ($attachment instanceof Post) { $attachment->setLikeRecursively($liked, $user, $depth + 1); + } + } + } } - + /** * May return fake owner (group), if flags are [1, (*)] - * + * * @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($this->getRecord()->wall < 0) - return (new Clubs)->get(abs($this->getRecord()->wall)); + if ($honourFlags && $this->isPostedOnBehalfOfGroup()) { + if ($this->getRecord()->wall < 0) { + return (new Clubs())->get(abs($this->getRecord()->wall)); + } } - + return parent::getOwner($real); } - - function getPrettyId(): string + + public function getPrettyId(): string { return $this->getRecord()->wall . "_" . $this->getVirtualId(); } - - function getTargetWall(): int + + public function getTargetWall(): int { return $this->getRecord()->wall; } - function getWallOwner() + public function getWallOwner() { $w = $this->getRecord()->wall; - if($w < 0) - return (new Clubs)->get(abs($w)); + if ($w < 0) { + 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( $this->getRecord() @@ -73,95 +84,97 @@ class Post extends Postable ->where("attachable_type", get_class($this)) ); } - - function isPinned(): bool + + public function isPinned(): bool { 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; - 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; + } - if(!$format) + if (!$format) { return $orig_source; - + } + return $this->formatLinks($orig_source); } - function setSource(string $source) + public function setSource(string $source) { $result = check_copyright_link($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, 'link' => $this->getSource(false), 'name' => $this->getSource(false), 'type' => 'link', ]; } - - function isAd(): bool + + public function isAd(): bool { return (bool) $this->getRecord()->ad; } - - function isPostedOnBehalfOfGroup(): bool + + public function isPostedOnBehalfOfGroup(): bool { return ($this->getRecord()->flags & 0b10000000) > 0; } - - function isSigned(): bool + + public function isSigned(): bool { return ($this->getRecord()->flags & 0b01000000) > 0; } - function isDeactivationMessage(): bool + public function isDeactivationMessage(): bool { 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); } - function isExplicit(): bool + public function isExplicit(): bool { return (bool) $this->getRecord()->nsfw; } - - function isDeleted(): bool + + public function isDeleted(): bool { return (bool) $this->getRecord()->deleted; } - - function getOwnerPost(): int + + public function getOwnerPost(): int { return $this->getOwner(false)->getId(); } - function getPlatform(bool $forAPI = false): ?string + public function getPlatform(bool $forAPI = false): ?string { $platform = $this->getRecord()->api_source_name; - if($forAPI) { + if ($forAPI) { switch ($platform) { case 'openvk_refresh_android': case 'openvk_legacy_android': @@ -176,16 +189,16 @@ class Post extends Postable case 'windows_phone': return 'wphone'; break; - + case 'vika_touch': // кика хохотач ахахахаххахахахахах case 'vk4me': return 'mobile'; break; - case NULL: - return NULL; + case null: + return null; break; - + default: return 'api'; 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"); - foreach($clients as $client) { - if($client['tag'] == $this->getPlatform()) { + foreach ($clients as $client) { + if ($client['tag'] == $this->getPlatform()) { return [ "tag" => $client['tag'], "name" => $client['name'], "url" => $client['url'], - "img" => $client['img'] + "img" => $client['img'], ]; break; } @@ -213,38 +226,40 @@ class Post extends Postable return [ "tag" => $this->getPlatform(), - "name" => NULL, - "url" => NULL, - "img" => NULL + "name" => null, + "url" => null, + "img" => null, ]; } - function getPostSourceInfo(): array + public function getPostSourceInfo(): array { $post_source = ["type" => "vk"]; - if($this->getPlatform(true) !== NULL) { + if ($this->getPlatform(true) !== null) { $post_source = [ "type" => "api", - "platform" => $this->getPlatform(true) + "platform" => $this->getPlatform(true), ]; } - if($this->isUpdateAvatarMessage()) + if ($this->isUpdateAvatarMessage()) { $post_source['data'] = 'profile_photo'; - + } + return $post_source; } - function getVkApiType(): string + public function getVkApiType(): string { $type = 'post'; - if($this->getSuggestionType() != 0) + if ($this->getSuggestionType() != 0) { $type = 'suggest'; + } return $type; } - - function pin(): void + + public function pin(): void { DB::i() ->getContext() @@ -254,98 +269,106 @@ class Post extends Postable "pinned" => true, ]) ->update(["pinned" => false]); - + $this->stateChanges("pinned", true); $this->save(); } - - function unpin(): void + + public function unpin(): void { $this->stateChanges("pinned", false); $this->save(); } - - function canBePinnedBy(User $user = NULL): bool - { - if(!$user) - return false; - if($this->getTargetWall() < 0) - return (new Clubs)->get(abs($this->getTargetWall()))->canBeModifiedBy($user); - + public function canBePinnedBy(User $user = null): bool + { + if (!$user) { + return false; + } + + if ($this->getTargetWall() < 0) { + return (new Clubs())->get(abs($this->getTargetWall()))->canBeModifiedBy($user); + } + return $this->getTargetWall() === $user->getId(); } - - function canBeDeletedBy(User $user = NULL): bool + + public function canBeDeletedBy(User $user = null): bool { - if(!$user) + if (!$user) { 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 $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)."); - 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."); - + } + $this->stateChanges("content", $content); } - function toggleLike(User $user): bool + public function toggleLike(User $user): bool { $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(); + } - foreach($this->getChildren() as $attachment) - if($attachment instanceof Post) + foreach ($this->getChildren() as $attachment) { + if ($attachment instanceof Post) { $attachment->setLikeRecursively($liked, $user, 2); + } + } return $liked; } - function setLike(bool $liked, User $user): void + public function setLike(bool $liked, User $user): void { $this->setLikeRecursively($liked, $user, 1); } - - function deletePost(): void + + public function deletePost(): void { $this->setDeleted(1); $this->unwire(); $this->save(); } - function canBeViewedBy(?User $user = NULL): bool + public function canBeViewedBy(?User $user = null): bool { - if($this->isDeleted()) { + if ($this->isDeleted()) { return false; } - + return $this->getWallOwner()->canBeViewedBy($user); } - - function getSuggestionType() + + public function getSuggestionType() { 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->to_id = $this->getOwner() instanceof Club ? $this->getOwner()->getId() * -1 : $this->getOwner()->getId(); $res->from_id = $res->to_id; @@ -353,97 +376,105 @@ class Post extends Postable $res->text = $this->getText(false); $res->attachments = []; # todo - $res->copy_owner_id = NULL; # todo - $res->copy_post_id = NULL; # todo + $res->copy_owner_id = null; # todo + $res->copy_post_id = null; # todo return $res; } - - function canBeEditedBy(?User $user = NULL): bool + + public function canBeEditedBy(?User $user = null): bool { - if(!$user) + if (!$user) { return false; + } - if($this->isDeactivationMessage() || $this->isUpdateAvatarMessage()) + if ($this->isDeactivationMessage() || $this->isUpdateAvatarMessage()) { return false; + } - if($this->getTargetWall() > 0) + if ($this->getTargetWall() > 0) { return $this->getPublicationTime()->timestamp() + WEEK > time() && $user->getId() == $this->getOwner(false)->getId(); - else { - if($this->isPostedOnBehalfOfGroup()) + } else { + if ($this->isPostedOnBehalfOfGroup()) { return $this->getWallOwner()->canBeModifiedBy($user); - else + } else { 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); $title = str_replace("\n", "", ovk_proc_strtr($description, 79)); $description_html = $description; - $url = $domain."/wall".$this->getPrettyId(); + $url = $domain . "/wall" . $this->getPrettyId(); - if($this->isUpdateAvatarMessage()) + if ($this->isUpdateAvatarMessage()) { $title = tr('upd_in_general'); - if($this->isDeactivationMessage()) + } + if ($this->isDeactivationMessage()) { $title = tr('post_deact_in_general'); + } $author = $this->getOwner(); $target_wall = $this->getWallOwner(); $author_name = escape_html($author->getCanonicalName()); - if($this->isExplicit()) + if ($this->isExplicit()) { $title = 'NSFW: ' . $title; + } - foreach($this->getChildren() as $child) { - if($child instanceof Photo) { - $child_page = $domain.$child->getPageURL(); + foreach ($this->getChildren() as $child) { + if ($child instanceof Photo) { + $child_page = $domain . $child->getPageURL(); $child_url = $child->getURL(); $description_html .= "

"; - } elseif($child instanceof Video) { - $child_page = $domain.'/video'.$child->getPrettyId(); + } elseif ($child instanceof Video) { + $child_page = $domain . '/video' . $child->getPrettyId(); - if($child->getType() != 1) { - $description_html .= "". - "
". - "
". - "".escape_html($child->getName())."
"; + if ($child->getType() != 1) { + $description_html .= "" . + "
" . + "
" . + "" . escape_html($child->getName()) . "
"; } else { - $description_html .= "". - "
". - "getVideoDriver()->getURL()."\">".escape_html($child->getName())."
"; + $description_html .= "" . + "
" . + "getVideoDriver()->getURL() . "\">" . escape_html($child->getName()) . "
"; } - } elseif($child instanceof Audio) { - if(!$child->isWithdrawn()) { + } elseif ($child instanceof Audio) { + if (!$child->isWithdrawn()) { $description_html .= "
" - ."".escape_html($child->getName()).":" - ."
" - ."" - ."
"; + . "" . escape_html($child->getName()) . ":" + . "
" + . "" + . "
"; } - } elseif($child instanceof Poll) { - $description_html .= "
".tr('poll').": ".escape_html($child->getTitle()); - } elseif($child instanceof Note) { - $description_html .= "
".tr('note').": ".escape_html($child->getName()); + } elseif ($child instanceof Poll) { + $description_html .= "
" . tr('poll') . ": " . escape_html($child->getTitle()); + } elseif ($child instanceof Note) { + $description_html .= "
" . tr('note') . ": " . escape_html($child->getName()); } } - $description_html .= "
".tr('author').": " . $author_name . ""; - - if($target_wall->getRealId() != $author->getRealId()) - $description_html .= "
".tr('on_wall').": " . escape_html($target_wall->getCanonicalName()) . ""; - - if($this->isSigned()) { - $signer = $this->getOwner(false); - $description_html .= "
".tr('sign_short').": " . escape_html($signer->getCanonicalName()) . ""; + $description_html .= "
" . tr('author') . ": " . $author_name . ""; + + if ($target_wall->getRealId() != $author->getRealId()) { + $description_html .= "
" . tr('on_wall') . ": " . escape_html($target_wall->getCanonicalName()) . ""; } - if($this->hasSource()) - $description_html .= "
".tr('source').": ".escape_html($this->getSource()); + if ($this->isSigned()) { + $signer = $this->getOwner(false); + $description_html .= "
" . tr('sign_short') . ": " . escape_html($signer->getCanonicalName()) . ""; + } + + if ($this->hasSource()) { + $description_html .= "
" . tr('source') . ": " . escape_html($this->getSource()); + } $item = new \Bhaktaraz\RSSGenerator\Item(); $item->title($title) @@ -456,39 +487,41 @@ class Post extends Postable 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); } - function setGeo($encoded_object): void + public function setGeo($encoded_object): void { $final_geo = $encoded_object['name']; $neutral_names = ["Россия", "Russia", "Росія", "Россія", "Украина", "Ukraine", "Україна", "Украіна"]; - foreach($neutral_names as $name) { - if(str_contains($final_geo, $name.", ")) { - $final_geo = str_replace($name.", ", "", $final_geo); + foreach ($neutral_names as $name) { + if (str_contains($final_geo, $name . ", ")) { + $final_geo = str_replace($name . ", ", "", $final_geo); } } - + $encoded_object['name'] = ovk_proc_strtr($final_geo, 255); $encoded = json_encode($encoded_object); $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) [ 'type' => 'point', @@ -496,6 +529,4 @@ class Post extends Postable 'name' => $this->getGeo()->name, ]; } - - use Traits\TRichText; } diff --git a/Web/Models/Entities/Postable.php b/Web/Models/Entities/Postable.php index 911ef4be..75d774b5 100644 --- a/Web/Models/Entities/Postable.php +++ b/Web/Models/Entities/Postable.php @@ -1,5 +1,9 @@ -getContext()->table($this->tableName); } - - function getOwner(bool $real = false): RowModel + + public function getOwner(bool $real = false): RowModel { $oid = (int) $this->getRecord()->owner; - if(!$real && $this->isAnonymous()) + if (!$real && $this->isAnonymous()) { $oid = (int) OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["account"]; + } $oid = abs($oid); - if($oid > 0) - return (new Users)->get($oid); - else - return (new Clubs)->get($oid * -1); + if ($oid > 0) { + return (new Users())->get($oid); + } else { + return (new Clubs())->get($oid * -1); + } } - - function getVirtualId(): int + + public function getVirtualId(): int { return $this->getRecord()->virtual_id; } - - function getPrettyId(): string + + public function getPrettyId(): string { return $this->getRecord()->owner . "_" . $this->getVirtualId(); } - - function getPublicationTime(): DateTime + + public function getPublicationTime(): DateTime { return new DateTime($this->getRecord()->created); } - - function getEditTime(): ?DateTime + + public function getEditTime(): ?DateTime { $edited = $this->getRecord()->edited; - if(is_null($edited)) return NULL; - + if (is_null($edited)) { + return null; + } + 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); - } - - function getCommentsCount(): int - { - return (new Comments)->getCommentsCountByTarget($this); + return (new Comments())->getCommentsByTarget($this, $page, $perPage); } - 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([ "model" => static::class, "target" => $this->getRecord()->id, ])->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; @@ -96,42 +106,42 @@ abstract class Postable extends Attachable "model" => static::class, "target" => $this->getRecord()->id, ])->page($page, $perPage); - - foreach($sel as $like) { - $user = (new Users)->get($like->origin); - if($user->isPrivateLikes() && OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["enable"]) { - $user = (new Users)->get((int) OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["account"]); + + foreach ($sel as $like) { + $user = (new Users())->get($like->origin); + if ($user->isPrivateLikes() && OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["enable"]) { + $user = (new Users())->get((int) OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["account"]); } yield $user; } } - function getAccessKey(): string + public function getAccessKey(): string { 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 !$this->isPrivate(); } - function isPrivate(): bool + public function isPrivate(): bool { return (bool) $this->getRecord()->unlisted; } - - function isAnonymous(): bool + + public function isAnonymous(): bool { return (bool) $this->getRecord()->anonymous; } - - function toggleLike(User $user): bool + + public function toggleLike(User $user): bool { $searchData = [ "origin" => $user->getId(), @@ -139,7 +149,7 @@ abstract class Postable extends Attachable "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(); return false; } @@ -148,7 +158,7 @@ abstract class Postable extends Attachable return true; } - function setLike(bool $liked, User $user): void + public function setLike(bool $liked, User $user): void { $searchData = [ "origin" => $user->getId(), @@ -156,55 +166,54 @@ abstract class Postable extends Attachable "target" => $this->getRecord()->id, ]; - if($liked) { - if(!$this->hasLikeFrom($user)) { - DB::i()->getContext()->table("likes")->insert($searchData); + if ($liked) { + if (!$this->hasLikeFrom($user)) { + DB::i()->getContext()->table("likes")->insert($searchData); } } else { - if($this->hasLikeFrom($user)) { + if ($this->hasLikeFrom($user)) { DB::i()->getContext()->table("likes")->where($searchData)->delete(); } - } + } } - - function hasLikeFrom(User $user): bool + + public function hasLikeFrom(User $user): bool { $searchData = [ "origin" => $user->getId(), "model" => static::class, "target" => $this->getRecord()->id, ]; - + return sizeof(DB::i()->getContext()->table("likes")->where($searchData)) > 0; } - - function setVirtual_Id(int $id): void + + public function setVirtual_Id(int $id): void { 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; - + $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?"); - + } + $pCount = sizeof($this->getTable()->where($vref, $vid)); - if(is_null($this->getRecord())) { + if (is_null($this->getRecord())) { # lol allow ppl to taint created value - if(!isset($this->changes["created"])) + if (!isset($this->changes["created"])) { $this->stateChanges("created", time()); - + } + $this->stateChanges("virtual_id", $pCount + 1); } /*else { $this->stateChanges("edited", time()); }*/ - + parent::save($log); } - - use Traits\TAttachmentHost; - use Traits\TOwnable; } diff --git a/Web/Models/Entities/Report.php b/Web/Models/Entities/Report.php index 3bb6b083..db8d38e6 100644 --- a/Web/Models/Entities/Report.php +++ b/Web/Models/Entities/Report.php @@ -1,161 +1,177 @@ -getRecord()->id; - } - - function getStatus(): int - { - return $this->getRecord()->status; - } - - function getContentType(): string - { - return $this->getRecord()->type; - } - - function getReason(): string - { - return $this->getRecord()->reason; - } - - function getTime(): DateTime - { - return new DateTime($this->getRecord()->date); - } - - function isDeleted(): bool - { - if ($this->getRecord()->deleted === 0) - { - return false; - } elseif ($this->getRecord()->deleted === 1) { - return true; - } - } - - function authorId(): int - { - return $this->getRecord()->user_id; - } - - function getUser(): User - { - return (new Users)->get((int) $this->getRecord()->user_id); - } - - function getContentId(): int - { - return (int) $this->getRecord()->target_id; - } - - function getContentObject() - { - if ($this->getContentType() == "post") return (new Posts)->get($this->getContentId()); - else if ($this->getContentType() == "photo") return (new Photos)->get($this->getContentId()); - else if ($this->getContentType() == "video") return (new Videos)->get($this->getContentId()); - else if ($this->getContentType() == "group") return (new Clubs)->get($this->getContentId()); - else if ($this->getContentType() == "comment") return (new Comments)->get($this->getContentId()); - else if ($this->getContentType() == "note") return (new Notes)->get($this->getContentId()); - else if ($this->getContentType() == "app") return (new Applications)->get($this->getContentId()); - else if ($this->getContentType() == "user") return (new Users)->get($this->getContentId()); - else if ($this->getContentType() == "audio") return (new Audios)->get($this->getContentId()); - else if ($this->getContentType() == "doc") return (new Documents)->get($this->getContentId()); - else return null; - } - - function getAuthor(): RowModel - { - return $this->getContentObject()->getOwner(); - } - - function getReportAuthor(): User - { - return (new Users)->get($this->getRecord()->user_id); - } - - function banUser($initiator) - { - $reason = $this->getContentType() !== "user" ? ("**content-" . $this->getContentType() . "-" . $this->getContentId() . "**") : ("Подозрительная активность"); - $this->getAuthor()->ban($reason, false, time() + $this->getAuthor()->getNewBanTime(), $initiator); - } - - function deleteContent() - { - if ($this->getContentType() !== "user") { - $pubTime = $this->getContentObject()->getPublicationTime(); - if (method_exists($this->getContentObject(), "getName")) { - $name = $this->getContentObject()->getName(); - $placeholder = "$pubTime ($name)"; - } else { - $placeholder = "$pubTime"; - } - - if ($this->getAuthor() instanceof Club) { - $name = $this->getAuthor()->getName(); - $this->getAuthor()->getOwner()->adminNotify("Ваш контент, который опубликовали $placeholder в созданной вами группе \"$name\" был удалён модераторами инстанса. За повторные или серьёзные нарушения группу могут заблокировать."); - } else { - $this->getAuthor()->adminNotify("Ваш контент, который вы опубликовали $placeholder был удалён модераторами инстанса. За повторные или серьёзные нарушения вас могут заблокировать."); - } - $this->getContentObject()->delete($this->getContentType() !== "app"); - } - - $this->delete(); - } - - function getDuplicates(): \Traversable - { - return (new Reports)->getDuplicates($this->getContentType(), $this->getContentId(), $this->getId()); - } - - function getDuplicatesCount(): int - { - return count(iterator_to_array($this->getDuplicates())); - } - - function hasDuplicates(): bool - { - return $this->getDuplicatesCount() > 0; - } - - function getContentName(): string - { - $content_object = $this->getContentObject(); - if(!$content_object) { - return 'unknown'; - } - - if (method_exists($content_object, "getCanonicalName")) - 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(); - } -} +getRecord()->id; + } + + public function getStatus(): int + { + return $this->getRecord()->status; + } + + public function getContentType(): string + { + return $this->getRecord()->type; + } + + public function getReason(): string + { + return $this->getRecord()->reason; + } + + public function getTime(): DateTime + { + return new DateTime($this->getRecord()->date); + } + + public function isDeleted(): bool + { + if ($this->getRecord()->deleted === 0) { + return false; + } elseif ($this->getRecord()->deleted === 1) { + return true; + } + } + + public function authorId(): int + { + return $this->getRecord()->user_id; + } + + public function getUser(): User + { + return (new Users())->get((int) $this->getRecord()->user_id); + } + + public function getContentId(): int + { + return (int) $this->getRecord()->target_id; + } + + public function getContentObject() + { + if ($this->getContentType() == "post") { + return (new Posts())->get($this->getContentId()); + } elseif ($this->getContentType() == "photo") { + return (new Photos())->get($this->getContentId()); + } elseif ($this->getContentType() == "video") { + return (new Videos())->get($this->getContentId()); + } elseif ($this->getContentType() == "group") { + return (new Clubs())->get($this->getContentId()); + } elseif ($this->getContentType() == "comment") { + return (new Comments())->get($this->getContentId()); + } elseif ($this->getContentType() == "note") { + return (new Notes())->get($this->getContentId()); + } elseif ($this->getContentType() == "app") { + return (new Applications())->get($this->getContentId()); + } elseif ($this->getContentType() == "user") { + return (new Users())->get($this->getContentId()); + } elseif ($this->getContentType() == "audio") { + return (new Audios())->get($this->getContentId()); + } elseif ($this->getContentType() == "doc") { + return (new Documents())->get($this->getContentId()); + } else { + return null; + } + } + + public function getAuthor(): RowModel + { + return $this->getContentObject()->getOwner(); + } + + public function getReportAuthor(): User + { + return (new Users())->get($this->getRecord()->user_id); + } + + public function banUser($initiator) + { + $reason = $this->getContentType() !== "user" ? ("**content-" . $this->getContentType() . "-" . $this->getContentId() . "**") : ("Подозрительная активность"); + $this->getAuthor()->ban($reason, false, time() + $this->getAuthor()->getNewBanTime(), $initiator); + } + + public function deleteContent() + { + if ($this->getContentType() !== "user") { + $pubTime = $this->getContentObject()->getPublicationTime(); + if (method_exists($this->getContentObject(), "getName")) { + $name = $this->getContentObject()->getName(); + $placeholder = "$pubTime ($name)"; + } else { + $placeholder = "$pubTime"; + } + + if ($this->getAuthor() instanceof Club) { + $name = $this->getAuthor()->getName(); + $this->getAuthor()->getOwner()->adminNotify("Ваш контент, который опубликовали $placeholder в созданной вами группе \"$name\" был удалён модераторами инстанса. За повторные или серьёзные нарушения группу могут заблокировать."); + } else { + $this->getAuthor()->adminNotify("Ваш контент, который вы опубликовали $placeholder был удалён модераторами инстанса. За повторные или серьёзные нарушения вас могут заблокировать."); + } + $this->getContentObject()->delete($this->getContentType() !== "app"); + } + + $this->delete(); + } + + public function getDuplicates(): \Traversable + { + return (new Reports())->getDuplicates($this->getContentType(), $this->getContentId(), $this->getId()); + } + + public function getDuplicatesCount(): int + { + return count(iterator_to_array($this->getDuplicates())); + } + + public function hasDuplicates(): bool + { + return $this->getDuplicatesCount() > 0; + } + + public function getContentName(): string + { + $content_object = $this->getContentObject(); + if (!$content_object) { + return 'unknown'; + } + + if (method_exists($content_object, "getCanonicalName")) { + 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(); + } +} diff --git a/Web/Models/Entities/SupportAgent.php b/Web/Models/Entities/SupportAgent.php index 2f7fc21b..3375ec12 100644 --- a/Web/Models/Entities/SupportAgent.php +++ b/Web/Models/Entities/SupportAgent.php @@ -1,5 +1,9 @@ -getRecord()->agent; } - function getName(): ?string + public function getName(): ?string { return $this->getRecord()->name; } - function getCanonicalName(): string + public function getCanonicalName(): string { return $this->getName(); } - function getAvatarURL(): ?string + public function getAvatarURL(): ?string { return $this->getRecord()->icon; } - function isShowNumber(): int + public function isShowNumber(): int { 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(); } -} \ No newline at end of file +} diff --git a/Web/Models/Entities/SupportAlias.php b/Web/Models/Entities/SupportAlias.php index 9ad618a6..49f817ce 100644 --- a/Web/Models/Entities/SupportAlias.php +++ b/Web/Models/Entities/SupportAlias.php @@ -1,38 +1,42 @@ -get($this->getRecord()->agent); + return (new Users())->get($this->getRecord()->agent); } - - function getName(): string + + public function getName(): string { return $this->getRecord()->name; } - - function getIcon(): ?string + + public function getIcon(): ?string { return $this->getRecord()->icon; } - - function shouldAppendNumber(): bool + + public function shouldAppendNumber(): bool { return (bool) $this->getRecord()->numerate; } - - function setAgent(User $agent): void + + public function setAgent(User $agent): void { $this->stateChanges("agent", $agent->getId()); } - - function setNumeration(bool $numerate): void + + public function setNumeration(bool $numerate): void { $this->stateChanges("numerate", $numerate); } diff --git a/Web/Models/Entities/Ticket.php b/Web/Models/Entities/Ticket.php index 31690ce3..9c1abd5e 100644 --- a/Web/Models/Entities/Ticket.php +++ b/Web/Models/Entities/Ticket.php @@ -1,36 +1,41 @@ -getRecord()->id; } - - function getStatus(): string + + public function getStatus(): string { return tr("support_status_" . $this->getRecord()->type); } - - function getType(): int + + public function getType(): int { return $this->getRecord()->type; } - - function getName(): string + + public function getName(): string { return ovk_proc_strtr($this->getRecord()->name, 100); } - - function getContext(): string + + public function getContext(): string { $text = $this->getRecord()->text; $text = $this->formatLinks($text); @@ -38,31 +43,29 @@ class Ticket extends RowModel $text = nl2br($text); return $text; } - - function getTime(): DateTime + + public function getTime(): DateTime { return new DateTime($this->getRecord()->created); } - - function isDeleted(): bool + + public function isDeleted(): bool { 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; } - function isAd(): bool /* Эх, костыли... */ + public function isAd(): bool /* Эх, костыли... */ { - return false; + return false; } - - use Traits\TRichText; } diff --git a/Web/Models/Entities/TicketComment.php b/Web/Models/Entities/TicketComment.php index 2f1a5e8f..65bd5f7f 100644 --- a/Web/Models/Entities/TicketComment.php +++ b/Web/Models/Entities/TicketComment.php @@ -1,100 +1,112 @@ -get($this->getUser()->getId()); + return (new SupportAliases())->get($this->getUser()->getId()); } - - function getId(): int + + public function getId(): int { return $this->getRecord()->id; } - function getUType(): int + public function getUType(): int { return $this->getRecord()->user_type; } - - function getUser(): User - { - return (new Users)->get($this->getRecord()->user_id); + + public function getUser(): User + { + 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(); - + } + $alias = $this->getSupportAlias(); - if(!$alias) + if (!$alias) { return tr("helpdesk_agent") . " #" . $this->getAgentNumber(); - + } + $name = $alias->getName(); - if($alias->shouldAppendNumber()) + if ($alias->shouldAppendNumber()) { $name .= " №" . $this->getAgentNumber(); - + } + return $name; } - - function getAvatar(): string + + public function getAvatar(): string { - if($this->getUType() === 0) + if ($this->getUType() === 0) { return $this->getUser()->getAvatarUrl(); - + } + $default = "/assets/packages/static/openvk/img/support.jpeg"; $alias = $this->getSupportAlias(); - + return is_null($alias) ? $default : ($alias->getIcon() ?? $default); } - - function getAgentNumber(): ?string + + public function getAgentNumber(): ?string { - if($this->getUType() === 0) - return NULL; - + if ($this->getUType() === 0) { + return null; + } + $salt = "kiraMiki"; $hash = $this->getUser()->getId() . CHANDLER_ROOT_CONF["security"]["secret"] . $salt; $hash = hexdec(substr(hash("adler32", $hash), 0, 3)); $hash = ceil(($hash * 999) / 4096); # proportionalize to 0-999 - + return str_pad((string) $hash, 3, "0", STR_PAD_LEFT); } - - function getColorRotation(): ?int + + public function getColorRotation(): ?int { - if(is_null($agent = $this->getAgentNumber())) - return NULL; - - if(!is_null($this->getSupportAlias())) + if (is_null($agent = $this->getAgentNumber())) { + return null; + } + + if (!is_null($this->getSupportAlias())) { return 0; - + } + $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 - usort($values, function($x, $y) use ($rotation) { + usort($values, function ($x, $y) use ($rotation) { # find closest return abs($x - $rotation) - abs($y - $rotation); }); - + return array_shift($values); } - - function getContext(): string + + public function getContext(): string { $text = $this->getRecord()->text; $text = $this->formatLinks($text); @@ -102,35 +114,34 @@ class TicketComment extends RowModel $text = nl2br($text); return $text; } - - function getTime(): DateTime + + public function getTime(): DateTime { return new DateTime($this->getRecord()->created); } - function isAd(): bool - { - return false; # Кооостыыыль!!! - } + public function isAd(): bool + { + return false; # Кооостыыыль!!! + } - function getMark(): ?int + public function getMark(): ?int { return $this->getRecord()->mark; } - function isLikedByUser(): ?bool + public function isLikedByUser(): ?bool { $mark = $this->getMark(); - if(is_null($mark)) - return NULL; - else + if (is_null($mark)) { + return null; + } else { return $mark === 1; + } } - function isDeleted(): bool + public function isDeleted(): bool { return (bool) $this->getRecord()->deleted; } - - use Traits\TRichText; } diff --git a/Web/Models/Entities/Topic.php b/Web/Models/Entities/Topic.php index d4257816..dfe010fc 100644 --- a/Web/Models/Entities/Topic.php +++ b/Web/Models/Entities/Topic.php @@ -1,5 +1,9 @@ -isPostedOnBehalfOfGroup()) + if ($honourFlags && $this->isPostedOnBehalfOfGroup()) { return $this->getClub(); - + } + 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; } - function isClosed(): bool + public function isClosed(): bool { return (bool) $this->getRecord()->closed; } - function isPinned(): bool + public function isPinned(): bool { return (bool) $this->getRecord()->pinned; } - function getPrettyId(): string + public function getPrettyId(): string { return $this->getRecord()->group . "_" . $this->getVirtualId(); } - function isPostedOnBehalfOfGroup(): bool + public function isPostedOnBehalfOfGroup(): bool { return ($this->getRecord()->flags & 0b10000000) > 0; } - function isDeleted(): bool + public function isDeleted(): bool { 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); } - function getLastComment(): ?Comment + public function getLastComment(): ?Comment { $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)); - return $array[0] ?? NULL; + return $array[0] ?? null; } - function getUpdateTime(): DateTime + public function getUpdateTime(): DateTime { $lastComment = $this->getLastComment(); - if(!is_null($lastComment)) + if (!is_null($lastComment)) { return $lastComment->getPublicationTime(); - else + } else { return $this->getEditTime() ?? $this->getPublicationTime(); + } } - function deleteTopic(): void + public function deleteTopic(): void { $this->setDeleted(1); $this->unwire(); $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->title = $this->getTitle(); $res->created = $this->getPublicationTime()->timestamp(); - if($this->getOwner() instanceof User) { + if ($this->getOwner() instanceof User) { $res->created_by = $this->getOwner()->getId(); } else { $res->created_by = $this->getOwner()->getId() * -1; } - + $res->updated = $this->getUpdateTime()->timestamp(); - if($this->getLastComment()) { - if($this->getLastComment()->getOwner() instanceof User) { + if ($this->getLastComment()) { + if ($this->getLastComment()->getOwner() instanceof User) { $res->updated_by = $this->getLastComment()->getOwner()->getId(); } else { $res->updated_by = $this->getLastComment()->getOwner()->getId() * -1; } } - $res->is_closed = (int)$this->isClosed(); - $res->is_fixed = (int)$this->isPinned(); + $res->is_closed = (int) $this->isClosed(); + $res->is_fixed = (int) $this->isPinned(); $res->comments = $this->getCommentsCount(); - if($preview == 1) { - $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; + if ($preview == 1) { + $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; } return $res; diff --git a/Web/Models/Entities/Traits/TAttachmentHost.php b/Web/Models/Entities/Traits/TAttachmentHost.php index a574e657..529fb65b 100644 --- a/Web/Models/Entities/Traits/TAttachmentHost.php +++ b/Web/Models/Entities/Traits/TAttachmentHost.php @@ -1,5 +1,9 @@ - $attachment->getId(), ]; } - - function getChildren(): \Traversable + + public function getChildren(): \Traversable { $sel = DatabaseConnection::i()->getContext() ->table("attachments") ->where("target_id", $this->getId()) ->where("attachments.target_type", get_class($this)); - foreach($sel as $rel) { + foreach ($sel as $rel) { $repoName = $rel->attachable_type . "s"; $repoName = str_replace("Entities", "Repositories", $repoName); - $repo = new $repoName; - + $repo = new $repoName(); + 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; + } $children = iterator_to_array($this->getChildren()); $skipped = $photos = $result = []; - foreach($children as $child) { - if($child instanceof Photo || $child instanceof Video && $child->getDimensions()) { + foreach ($children as $child) { + if ($child instanceof Photo || $child instanceof Video && $child->getDimensions()) { $photos[] = $child; continue; } @@ -49,15 +54,16 @@ trait TAttachmentHost $height = "unset"; $width = $w; - if(sizeof($photos) < 2) { - if(isset($photos[0])) + if (sizeof($photos) < 2) { + if (isset($photos[0])) { $result[] = ["100%", "unset", $photos[0], "unset"]; + } } else { $mak = new Makima($photos); $layout = $mak->computeMasonryLayout($w, $h); $height = $layout->height; $width = $layout->width; - for($i = 0; $i < sizeof($photos); $i++) { + for ($i = 0; $i < sizeof($photos); $i++) { $tile = $layout->tiles[$i]; $result[] = [$tile->width . "px", $tile->height . "px", $photos[$i], "left"]; } @@ -70,25 +76,25 @@ trait TAttachmentHost "extras" => $skipped, ]; } - - function attach(Attachable $attachment): void + + public function attach(Attachable $attachment): void { DatabaseConnection::i()->getContext() ->table("attachments") ->insert($this->composeAttachmentRequestData($attachment)); } - - function detach(Attachable $attachment): bool + + public function detach(Attachable $attachment): bool { $res = DatabaseConnection::i()->getContext() ->table("attachments") ->where($this->composeAttachmentRequestData($attachment)) ->delete(); - + return $res > 0; } - - function unwire(): void + + public function unwire(): void { $this->getRecord() ->related("attachments.target_id") diff --git a/Web/Models/Entities/Traits/TAudioStatuses.php b/Web/Models/Entities/Traits/TAudioStatuses.php index f957a104..544e1e6e 100644 --- a/Web/Models/Entities/Traits/TAudioStatuses.php +++ b/Web/Models/Entities/Traits/TAudioStatuses.php @@ -1,27 +1,38 @@ -getRealId() < 0) return true; + if ($this->getRealId() < 0) { + return true; + } 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; - if(!$audioId) return NULL; - $audio = (new Audios)->get($audioId); + if (!$audioId) { + return null; + } + $audio = (new Audios())->get($audioId); - if(!$audio || $audio->isDeleted()) - return NULL; + if (!$audio || $audio->isDeleted()) { + return null; + } $listensTable = DatabaseConnection::i()->getContext()->table("audio_listens"); $lastListen = $listensTable->where([ @@ -30,9 +41,10 @@ trait TAudioStatuses "time >" => (time() - $audio->getLength()) - 10, ])->fetch(); - if($lastListen) + if ($lastListen) { return $audio; + } - return NULL; + return null; } } diff --git a/Web/Models/Entities/Traits/TBackDrops.php b/Web/Models/Entities/Traits/TBackDrops.php index cab67138..c48c73fe 100644 --- a/Web/Models/Entities/Traits/TBackDrops.php +++ b/Web/Models/Entities/Traits/TBackDrops.php @@ -1,44 +1,54 @@ -getRecord()->backdrop_1; $photo2 = $this->getRecord()->backdrop_2; - if(is_null($photo1) && is_null($photo2)) - return NULL; - - $photo1obj = $photo2obj = NULL; - if(!is_null($photo1)) - $photo1obj = (new Photos)->get($photo1); - if(!is_null($photo2)) - $photo2obj = (new Photos)->get($photo2); - - if(is_null($photo1obj) && is_null($photo2obj)) - return NULL; - + if (is_null($photo1) && is_null($photo2)) { + return null; + } + + $photo1obj = $photo2obj = null; + if (!is_null($photo1)) { + $photo1obj = (new Photos())->get($photo1); + } + if (!is_null($photo2)) { + $photo2obj = (new Photos())->get($photo2); + } + + if (is_null($photo1obj) && is_null($photo2obj)) { + return null; + } + return [ is_null($photo1obj) ? "" : $photo1obj->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()); - - if(!is_null($second)) + } + + if (!is_null($second)) { $this->stateChanges("backdrop_2", $second->getId()); + } } - - function unsetBackDropPictures(): void + + public function unsetBackDropPictures(): void { - $this->stateChanges("backdrop_1", NULL); - $this->stateChanges("backdrop_2", NULL); + $this->stateChanges("backdrop_1", null); + $this->stateChanges("backdrop_2", null); } -} \ No newline at end of file +} diff --git a/Web/Models/Entities/Traits/TIgnorable.php b/Web/Models/Entities/Traits/TIgnorable.php index 3e21420b..5413a40a 100644 --- a/Web/Models/Entities/Traits/TIgnorable.php +++ b/Web/Models/Entities/Traits/TIgnorable.php @@ -1,15 +1,20 @@ -getContext(); $data = [ "owner" => $user->getId(), @@ -20,29 +25,29 @@ trait TIgnorable return $sub->count() > 0; } - function addIgnore(User $for_user): bool + public function addIgnore(User $for_user): bool { DatabaseConnection::i()->getContext()->table("ignored_sources")->insert([ "owner" => $for_user->getId(), "source" => $this->getRealId(), ]); - + return true; } - function removeIgnore(User $for_user): bool + public function removeIgnore(User $for_user): bool { DatabaseConnection::i()->getContext()->table("ignored_sources")->where([ "owner" => $for_user->getId(), "source" => $this->getRealId(), ])->delete(); - + 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); return false; diff --git a/Web/Models/Entities/Traits/TOwnable.php b/Web/Models/Entities/Traits/TOwnable.php index 90182ddf..e4b27237 100644 --- a/Web/Models/Entities/Traits/TOwnable.php +++ b/Web/Models/Entities/Traits/TOwnable.php @@ -1,28 +1,35 @@ -isDeleted()) { + if ($this->isDeleted()) { return false; } - + return true; } - function canBeModifiedBy(User $user): bool + public function canBeModifiedBy(User $user): bool { - if(method_exists($this, "isCreatedBySystem")) - if($this->isCreatedBySystem()) + if (method_exists($this, "isCreatedBySystem")) { + if ($this->isCreatedBySystem()) { return false; - - if($this->getRecord()->owner > 0) + } + } + + if ($this->getRecord()->owner > 0) { return $this->getRecord()->owner === $user->getId(); - else + } else { return $this->getOwner()->canBeModifiedBy($user); + } } } diff --git a/Web/Models/Entities/Traits/TRichText.php b/Web/Models/Entities/Traits/TRichText.php index 0ffa2363..f82626e2 100644 --- a/Web/Models/Entities/Traits/TRichText.php +++ b/Web/Models/Entities/Traits/TRichText.php @@ -1,5 +1,9 @@ -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; - + } + $emojis = \Emoji\detect_emoji($text); $replaced = []; # OVK-113 - foreach($emojis as $emoji) { + foreach ($emojis as $emoji) { $point = explode("-", strtolower($emoji["hex_str"]))[0]; - if(in_array($point, $replaced)) + if (in_array($point, $replaced)) { continue; - else + } else { $replaced[] = $point; - + } + $image = "https://abs.twimg.com/emoji/v2/72x72/$point.png"; $image = "$emoji[emoji]$link" . htmlentities($matches[4]); } $link = htmlentities(urldecode($link));*/ - + return "$link" . htmlentities($matches[4]); }), $text ); } - + private function removeZalgo(string $text): string { 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"; $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("%([\n\r\s]|^)(@([A-Za-z0-9]++))%Xu", "$1[$3|@$3]", $text); - + $resolvedUsers = $skipUsers; $resolvedClubs = []; 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) { - if(preg_match("%^id([0-9]++)$%", $link, $match)) { + foreach ($links[1] as $link) { + if (preg_match("%^id([0-9]++)$%", $link, $match)) { $uid = (int) $match[1]; - if(in_array($uid, $resolvedUsers)) + if (in_array($uid, $resolvedUsers)) { continue; - + } + $resolvedUsers[] = $uid; - $maybeUser = (new Users)->get($uid); - if($maybeUser) + $maybeUser = (new Users())->get($uid); + if ($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]; - if(in_array($cid, $resolvedClubs)) + if (in_array($cid, $resolvedClubs)) { continue; - + } + $resolvedClubs[] = $cid; - $maybeClub = (new Clubs)->get($cid); - if($maybeClub) + $maybeClub = (new Clubs())->get($cid); + if ($maybeClub) { yield $maybeClub; + } } else { - $maybeUser = (new Users)->getByShortURL($link); - if($maybeUser) { + $maybeUser = (new Users())->getByShortURL($link); + if ($maybeUser) { $uid = $maybeUser->getId(); - if(in_array($uid, $resolvedUsers)) + if (in_array($uid, $resolvedUsers)) { continue; - else + } else { $resolvedUsers[] = $uid; - + } + yield $maybeUser; continue; } - - $maybeClub = (new Clubs)->getByShortURL($link); - if($maybeClub) { + + $maybeClub = (new Clubs())->getByShortURL($link); + if ($maybeClub) { $cid = $maybeClub->getId(); - if(in_array($cid, $resolvedClubs)) + if (in_array($cid, $resolvedClubs)) { continue; - else + } else { $resolvedClubs[] = $cid; - + } + yield $maybeClub; } } } } - - function getText(bool $html = true): string + + public function getText(bool $html = true): string { $contentColumn = property_exists($this, "overrideContentColumn") ? $this->overrideContentColumn : "content"; - + $text = htmlspecialchars($this->getRecord()->{$contentColumn}, ENT_DISALLOWED | ENT_XHTML); $proc = iconv_strlen($this->getRecord()->{$contentColumn}) <= OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["processingLimit"]; - if($html) { - if($proc) { + if ($html) { + if ($proc) { $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("%([\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", "$2", $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]); - + return "$m[1]$m[2]"; }, $text); - + $text = $this->formatEmojis($text); } - + $text = $this->removeZalgo($text); $text = nl2br($text); } 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); - + } + return $text; } } diff --git a/Web/Models/Entities/Traits/TSubscribable.php b/Web/Models/Entities/Traits/TSubscribable.php index 7d1c0d28..898f33a8 100644 --- a/Web/Models/Entities/Traits/TSubscribable.php +++ b/Web/Models/Entities/Traits/TSubscribable.php @@ -1,5 +1,9 @@ - static::class, "target" => $this->getId(), ]); - + foreach($subs as $sub) { $sub = (new Users)->get($sub->follower); if(!$sub) continue; - + yield $sub; } }*/ - - function toggleSubscription(User $user): bool + + public function toggleSubscription(User $user): bool { $ctx = DatabaseConnection::i()->getContext(); $data = [ @@ -30,17 +34,17 @@ trait TSubscribable "target" => $this->getId(), ]; $sub = $ctx->table("subscriptions")->where($data); - - if(!($sub->fetch())) { + + if (!($sub->fetch())) { $ctx->table("subscriptions")->insert($data); return true; } - + $sub->delete(); 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(); $data = [ @@ -51,12 +55,13 @@ trait TSubscribable $sub = $ctx->table("subscriptions")->where($data); bdump($data); - - if (!$sub) + + if (!$sub) { return false; + } $sub->update([ - 'flags' => $flags + 'flags' => $flags, ]); return true; } diff --git a/Web/Models/Entities/User.php b/Web/Models/Entities/User.php index 2b35fd2f..31d3d4fe 100644 --- a/Web/Models/Entities/User.php +++ b/Web/Models/Entities/User.php @@ -1,5 +1,9 @@ -getId(); $query = "SELECT id FROM\n" . file_get_contents(__DIR__ . "/../sql/$filename.tsql"); - $query .= "\n LIMIT " . $limit . " OFFSET " . ( ($page - 1) * $limit ); - + $query .= "\n LIMIT " . $limit . " OFFSET " . (($page - 1) * $limit); + $ids = []; $rels = DatabaseConnection::i()->getConnection()->query($query, $id, $id); - foreach($rels as $rel) { - $rel = (new Users)->get($rel->id); - if(!$rel) continue; - if(in_array($rel->getId(), $ids)) continue; + foreach ($rels as $rel) { + $rel = (new Users())->get($rel->id); + if (!$rel) { + continue; + } + if (in_array($rel->getId(), $ids)) { + continue; + } $ids[] = $rel->getId(); yield $rel; } } - + protected function _abstractRelationCount(string $filename): int { $id = $this->getId(); $query = "SELECT COUNT(*) AS cnt FROM\n" . file_get_contents(__DIR__ . "/../sql/$filename.tsql"); - + return (int) DatabaseConnection::i()->getConnection()->query($query, $id, $id)->fetch()->cnt; } - - function getId(): int + + public function getId(): int { return $this->getRecord()->id; } - - function getStyle(): string + + public function getStyle(): string { return $this->getRecord()->style; } - - function getTheme(): ?Themepack + + public function getTheme(): ?Themepack { - return Themepacks::i()[$this->getStyle()] ?? NULL; + return Themepacks::i()[$this->getStyle()] ?? null; } - - function getStyleAvatar(): int + + public function getStyleAvatar(): int { return $this->getRecord()->style_avatar; } - - function hasMilkshakeEnabled(): bool + + public function hasMilkshakeEnabled(): bool { return (bool) $this->getRecord()->milkshake; } - function hasMicroblogEnabled(): bool + public function hasMicroblogEnabled(): bool { return (bool) $this->getRecord()->microblog; } - function getMainPage(): int + public function getMainPage(): int { return $this->getRecord()->main_page; } - - function getChandlerGUID(): string + + public function getChandlerGUID(): string { return $this->getRecord()->user; } - - function getChandlerUser(): ChandlerUser + + public function getChandlerUser(): ChandlerUser { return new ChandlerUser($this->getRecord()->ref("ChandlerUsers", "user")); } - - function getURL(): string + + public function getURL(): string { - if(!is_null($this->getShortCode())) + if (!is_null($this->getShortCode())) { return "/" . $this->getShortCode(); - else + } else { return "/id" . $this->getId(); + } } - - function getAvatarUrl(string $size = "miniscule", $avPhoto = NULL): string + + public function getAvatarUrl(string $size = "miniscule", $avPhoto = null): string { $serverUrl = ovk_scheme(true) . $_SERVER["HTTP_HOST"]; - - if($this->getRecord()->deleted) + + if ($this->getRecord()->deleted) { return "$serverUrl/assets/packages/static/openvk/img/camera_200.png"; - else if($this->isBanned()) + } elseif ($this->isBanned()) { return "$serverUrl/assets/packages/static/openvk/img/banned.jpg"; - - if(!$avPhoto) + } + + if (!$avPhoto) { $avPhoto = $this->getAvatarPhoto(); - - if(is_null($avPhoto)) + } + + if (is_null($avPhoto)) { return "$serverUrl/assets/packages/static/openvk/img/camera_200.png"; - else + } else { return $avPhoto->getURLBySizeId($size); + } } - - function getAvatarLink(): string + + public function getAvatarLink(): string { $avPhoto = $this->getAvatarPhoto(); - if(!$avPhoto) return "javascript:void(0)"; - + if (!$avPhoto) { + return "javascript:void(0)"; + } + $pid = $avPhoto->getPrettyId(); - $aid = (new Albums)->getUserAvatarAlbum($this)->getId(); - + $aid = (new Albums())->getUserAvatarAlbum($this)->getId(); + return "/photo$pid?from=album$aid"; } - - function getAvatarPhoto(): ?Photo + + public function getAvatarPhoto(): ?Photo { - $avAlbum = (new Albums)->getUserAvatarAlbum($this); + $avAlbum = (new Albums())->getUserAvatarAlbum($this); $avCount = $avAlbum->getPhotosCount(); $avPhotos = $avAlbum->getPhotos($avCount, 1); - - return iterator_to_array($avPhotos)[0] ?? NULL; + + return iterator_to_array($avPhotos)[0] ?? null; } - - function getFirstName(bool $pristine = false): string + + public function getFirstName(bool $pristine = false): string { $name = ($this->isDeleted() && !$this->isDeactivated() ? "DELETED" : mb_convert_case($this->getRecord()->first_name, MB_CASE_TITLE)); - $tsn = tr("__transNames"); - if(( $tsn !== "@__transNames" && !empty($tsn) ) && !$pristine) + $tsn = tr("__transNames"); + if (($tsn !== "@__transNames" && !empty($tsn)) && !$pristine) { return mb_convert_case(transliterator_transliterate($tsn, $name), MB_CASE_TITLE); - else + } else { return $name; + } } - - function getLastName(bool $pristine = false): string + + public function getLastName(bool $pristine = false): string { $name = ($this->isDeleted() && !$this->isDeactivated() ? "DELETED" : mb_convert_case($this->getRecord()->last_name, MB_CASE_TITLE)); - $tsn = tr("__transNames"); - if(( $tsn !== "@__transNames" && !empty($tsn) ) && !$pristine) + $tsn = tr("__transNames"); + if (($tsn !== "@__transNames" && !empty($tsn)) && !$pristine) { return mb_convert_case(transliterator_transliterate($tsn, $name), MB_CASE_TITLE); - else + } else { return $name; + } } - - function getPseudo(): ?string + + public function getPseudo(): ?string { return ($this->isDeleted() && !$this->isDeactivated() ? "DELETED" : $this->getRecord()->pseudo); } - - function getFullName(): string + + public function getFullName(): string { - if($this->isDeleted() && !$this->isDeactivated()) + if ($this->isDeleted() && !$this->isDeactivated()) { return "DELETED"; - + } + $pseudo = $this->getPseudo(); - if(!$pseudo) + if (!$pseudo) { $pseudo = " "; - else + } else { $pseudo = " ($pseudo) "; - + } + return $this->getFirstName() . $pseudo . $this->getLastName(); } - function getMorphedName(string $case = "genitive", bool $fullName = true): string + public function getMorphedName(string $case = "genitive", bool $fullName = true): string { $name = $fullName ? ($this->getLastName() . " " . $this->getFirstName()) : $this->getFirstName(); - if(!preg_match("%[А-яё\-]+$%", $name)) - return $name; # name is probably not russian + if (!preg_match("%[А-яё\-]+$%", $name)) { + return $name; + } # name is probably not russian $inflected = inflectName($name, $case, $this->isFemale() ? Gender::FEMALE : Gender::MALE); return $inflected ?: $name; } - - function getCanonicalName(): string + + public function getCanonicalName(): string { - if($this->isDeleted() && !$this->isDeactivated()) + if ($this->isDeleted() && !$this->isDeactivated()) { return "DELETED"; - else + } else { return $this->getFirstName() . " " . $this->getLastName(); + } } - function getPhone(): ?string + public function getPhone(): ?string { return $this->getRecord()->phone; } - function getEmail(): ?string + public function getEmail(): ?string { return $this->getRecord()->email; } - function getOnline(): DateTime + public function getOnline(): DateTime { return new DateTime($this->getRecord()->online); } - function getDescription(): ?string + public function getDescription(): ?string { return $this->getRecord()->about; } - function getAbout(): ?string + public function getAbout(): ?string { return $this->getRecord()->about; } - function getStatus(): ?string + public function getStatus(): ?string { return $this->getRecord()->status; } - function getShortCode(): ?string + public function getShortCode(): ?string { return $this->getRecord()->shortcode; } - function getAlert(): ?string + public function getAlert(): ?string { return $this->getRecord()->alert; } - function getTextForContentBan(string $type): string + public function getTextForContentBan(string $type): string { switch ($type) { case "post": return "за размещение от Вашего лица таких записей:"; @@ -262,21 +287,24 @@ class User extends RowModel } } - function getRawBanReason(): ?string + public function getRawBanReason(): ?string { return $this->getRecord()->block_reason; } - function getBanReason(?string $for = null) + public function getBanReason(?string $for = null) { - $ban = (new Bans)->get((int) $this->getRecord()->block_reason); - if (!$ban || $ban->isOver()) return null; + $ban = (new Bans())->get((int) $this->getRecord()->block_reason); + if (!$ban || $ban->isOver()) { + return null; + } $reason = $ban->getReason(); preg_match('/\*\*content-(post|photo|video|group|comment|note|app|noSpamTemplate|user)-(\d+)\*\*$/', $reason, $matches); if (sizeof($matches) === 3) { - $content_type = $matches[1]; $content_id = (int) $matches[2]; + $content_type = $matches[1]; + $content_id = (int) $matches[2]; if (in_array($content_type, ["noSpamTemplate", "user"])) { $reason = "Подозрительная активность"; } else { @@ -285,14 +313,22 @@ class User extends RowModel } else { $reason = [$this->getTextForContentBan($content_type), $content_type]; switch ($content_type) { - case "post": $reason[] = (new Posts)->get($content_id); break; - case "photo": $reason[] = (new Photos)->get($content_id); break; - case "video": $reason[] = (new Videos)->get($content_id); break; - case "group": $reason[] = (new Clubs)->get($content_id); break; - case "comment": $reason[] = (new Comments)->get($content_id); break; - case "note": $reason[] = (new Notes)->get($content_id); break; - case "app": $reason[] = (new Applications)->get($content_id); break; - case "user": $reason[] = (new Users)->get($content_id); break; + case "post": $reason[] = (new Posts())->get($content_id); + break; + case "photo": $reason[] = (new Photos())->get($content_id); + break; + case "video": $reason[] = (new Videos())->get($content_id); + break; + case "group": $reason[] = (new Clubs())->get($content_id); + break; + case "comment": $reason[] = (new Comments())->get($content_id); + break; + case "note": $reason[] = (new Notes())->get($content_id); + break; + case "app": $reason[] = (new Applications())->get($content_id); + break; + case "user": $reason[] = (new Users())->get($content_id); + break; default: $reason[] = null; } } @@ -302,140 +338,146 @@ class User extends RowModel return $reason; } - function getBanInSupportReason(): ?string + public function getBanInSupportReason(): ?string { return $this->getRecord()->block_in_support_reason; } - function getType(): int + public function getType(): int { return $this->getRecord()->type; } - function getCoins(): float + public function getCoins(): float { - if(!OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"]) + if (!OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"]) { return 0.0; + } return $this->getRecord()->coins; } - function getRating(): int + public function getRating(): int { return OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"] ? $this->getRecord()->rating : 0; } - function getReputation(): int + public function getReputation(): int { return $this->getRecord()->reputation; } - function getRegistrationTime(): DateTime + public function getRegistrationTime(): DateTime { return new DateTime($this->getRecord()->since->getTimestamp()); } - function getRegistrationIP(): string + public function getRegistrationIP(): string { return $this->getRecord()->registering_ip; } - function getHometown(): ?string + public function getHometown(): ?string { return $this->getRecord()->hometown; } - function getPoliticalViews(): int + public function getPoliticalViews(): int { return $this->getRecord()->polit_views; } - function getMaritalStatus(): int + public function getMaritalStatus(): int { return $this->getRecord()->marital_status; } - - function getLocalizedMaritalStatus(?bool $prefix = false): string + + public function getLocalizedMaritalStatus(?bool $prefix = false): string { $status = $this->getMaritalStatus(); $string = "relationship_$status"; - if ($prefix) $string .= "_prefix"; - if($this->isFemale()) { - $res = tr($string . "_fem"); - if($res != ("@" . $string . "_fem")) - return $res; # If fem version exists, return + if ($prefix) { + $string .= "_prefix"; } - + if ($this->isFemale()) { + $res = tr($string . "_fem"); + if ($res != ("@" . $string . "_fem")) { + return $res; + } # If fem version exists, return + } + return tr($string); } - function getMaritalStatusUser(): ?User + public function getMaritalStatusUser(): ?User { - if (!$this->getRecord()->marital_status_user) return NULL; - return (new Users)->get($this->getRecord()->marital_status_user); + if (!$this->getRecord()->marital_status_user) { + return null; + } + return (new Users())->get($this->getRecord()->marital_status_user); } - function getMaritalStatusUserPrefix(): ?string + public function getMaritalStatusUserPrefix(): ?string { return $this->getLocalizedMaritalStatus(true); } - function getContactEmail(): ?string + public function getContactEmail(): ?string { return $this->getRecord()->email_contact; } - function getTelegram(): ?string + public function getTelegram(): ?string { return $this->getRecord()->telegram; } - function getInterests(): ?string + public function getInterests(): ?string { return $this->getRecord()->interests; } - function getFavoriteMusic(): ?string + public function getFavoriteMusic(): ?string { return $this->getRecord()->fav_music; } - function getFavoriteFilms(): ?string + public function getFavoriteFilms(): ?string { return $this->getRecord()->fav_films; } - function getFavoriteShows(): ?string + public function getFavoriteShows(): ?string { return $this->getRecord()->fav_shows; } - function getFavoriteBooks(): ?string + public function getFavoriteBooks(): ?string { return $this->getRecord()->fav_books; } - function getFavoriteQuote(): ?string + public function getFavoriteQuote(): ?string { return $this->getRecord()->fav_quote; } - function getFavoriteGames(): ?string + public function getFavoriteGames(): ?string { return $this->getRecord()->fav_games; } - function getCity(): ?string + public function getCity(): ?string { return $this->getRecord()->city; } - function getPhysicalAddress(): ?string + public function getPhysicalAddress(): ?string { return $this->getRecord()->address; } - function getAdditionalFields(bool $split = false): array + public function getAdditionalFields(bool $split = false): array { $all = \openvk\Web\Models\Entities\UserInfoEntities\AdditionalField::getByOwner($this->getId()); $result = [ @@ -443,61 +485,64 @@ class User extends RowModel "contacts" => [], ]; - if($split) { - foreach($all as $field) { - if($field->getPlace() == "contact") + if ($split) { + foreach ($all as $field) { + if ($field->getPlace() == "contact") { $result["contacts"][] = $field; - else if($field->getPlace() == "interest") + } elseif ($field->getPlace() == "interest") { $result["interests"][] = $field; + } } } else { $result = []; - foreach($all as $field) + foreach ($all as $field) { $result[] = $field; + } } return $result; } - function getNotificationOffset(): int + public function getNotificationOffset(): int { return $this->getRecord()->notification_offset; } - function getBirthday(): ?DateTime + public function getBirthday(): ?DateTime { - if(is_null($this->getRecord()->birthday)) - return NULL; - else + if (is_null($this->getRecord()->birthday)) { + return null; + } else { return new DateTime($this->getRecord()->birthday); + } } - function getBirthdayPrivacy(): int + public function getBirthdayPrivacy(): int { return $this->getRecord()->birthday_privacy; } - function getAge(): ?int + public function getAge(): ?int { - return (int)floor((time() - $this->getBirthday()->timestamp()) / YEAR); + return (int) floor((time() - $this->getBirthday()->timestamp()) / YEAR); } - function get2faSecret(): ?string + public function get2faSecret(): ?string { return $this->getRecord()["2fa_secret"]; } - function is2faEnabled(): bool + public function is2faEnabled(): bool { return !is_null($this->get2faSecret()); } - function updateNotificationOffset(): void + public function updateNotificationOffset(): void { $this->stateChanges("notification_offset", time()); } - function getLeftMenuItemStatus(string $id): bool + public function getLeftMenuItemStatus(string $id): bool { return (bool) bmask($this->getRecord()->left_menu, [ "length" => 1, @@ -517,7 +562,7 @@ class User extends RowModel ])->get($id); } - function getPrivacySetting(string $id): int + public function getPrivacySetting(string $id): int { return (int) bmask($this->getRecord()->privacy, [ "length" => 2, @@ -538,18 +583,20 @@ class User extends RowModel ])->get($id); } - function getPrivacyPermission(string $permission, ?User $user = NULL): bool + public function getPrivacyPermission(string $permission, ?User $user = null): bool { $permStatus = $this->getPrivacySetting($permission); - if(!$user) + if (!$user) { return $permStatus === User::PRIVACY_EVERYONE; - else if($user->getId() === $this->getId()) + } elseif ($user->getId() === $this->getId()) { return true; + } - if(/*$permission != "messages.write" && */!$this->canBeViewedBy($user, true)) + if (/*$permission != "messages.write" && */!$this->canBeViewedBy($user, true)) { return false; + } - switch($permStatus) { + switch ($permStatus) { case User::PRIVACY_ONLY_FRIENDS: return $this->getSubscriptionStatus($user) === User::SUBSCRIPTION_MUTUAL; case User::PRIVACY_ONLY_REGISTERED: @@ -560,38 +607,40 @@ class User extends RowModel } } - function getProfileCompletenessReport(): object + public function getProfileCompletenessReport(): object { $incompleteness = 0; $unfilled = []; - if(!$this->getRecord()->status) { + if (!$this->getRecord()->status) { $unfilled[] = "status"; $incompleteness += 15; } - if(!$this->getRecord()->telegram) { + if (!$this->getRecord()->telegram) { $unfilled[] = "telegram"; $incompleteness += 15; } - if(!$this->getRecord()->email) { + if (!$this->getRecord()->email) { $unfilled[] = "email"; $incompleteness += 20; } - if(!$this->getRecord()->city) { + if (!$this->getRecord()->city) { $unfilled[] = "city"; $incompleteness += 20; } - if(!$this->getRecord()->interests) { + if (!$this->getRecord()->interests) { $unfilled[] = "interests"; $incompleteness += 20; } $total = max(100 - $incompleteness + $this->getRating(), 0); - if(ovkGetQuirk("profile.rating-bar-behaviour") === 0) - if ($total >= 100) - $percent = round(($total / 10**strlen(strval($total))) * 100, 0); - else - $percent = min($total, 100); + if (ovkGetQuirk("profile.rating-bar-behaviour") === 0) { + if ($total >= 100) { + $percent = round(($total / 10 ** strlen(strval($total))) * 100, 0); + } else { + $percent = min($total, 100); + } + } return (object) [ "total" => $total, @@ -600,92 +649,97 @@ class User extends RowModel ]; } - function getFriends(int $page = 1, int $limit = 6): \Traversable + public function getFriends(int $page = 1, int $limit = 6): \Traversable { return $this->_abstractRelationGenerator("get-friends", $page, $limit); } - function getFriendsCount(): int + public function getFriendsCount(): int { return $this->_abstractRelationCount("get-friends"); } - function getFriendsOnline(int $page = 1, int $limit = 6): \Traversable + public function getFriendsOnline(int $page = 1, int $limit = 6): \Traversable { return $this->_abstractRelationGenerator("get-online-friends", $page, $limit); } - function getFriendsOnlineCount(): int + public function getFriendsOnlineCount(): int { return $this->_abstractRelationCount("get-online-friends"); } - function getFollowers(int $page = 1, int $limit = 6): \Traversable + public function getFollowers(int $page = 1, int $limit = 6): \Traversable { return $this->_abstractRelationGenerator("get-followers", $page, $limit); } - function getFollowersCount(): int + public function getFollowersCount(): int { return $this->_abstractRelationCount("get-followers"); } - function getRequests(int $page = 1, int $limit = 6): \Traversable + public function getRequests(int $page = 1, int $limit = 6): \Traversable { return $this->_abstractRelationGenerator("get-requests", $page, $limit); } - function getRequestsCount(): int + public function getRequestsCount(): int { return $this->_abstractRelationCount("get-requests"); } - function getSubscriptions(int $page = 1, int $limit = 6): \Traversable + public function getSubscriptions(int $page = 1, int $limit = 6): \Traversable { return $this->_abstractRelationGenerator("get-subscriptions-user", $page, $limit); } - function getSubscriptionsCount(): int + public function getSubscriptionsCount(): int { return $this->_abstractRelationCount("get-subscriptions-user"); } - function getUnreadMessagesCount(): int + public function getUnreadMessagesCount(): int { return sizeof(DatabaseConnection::i()->getContext()->table("messages")->where(["recipient_id" => $this->getId(), "unread" => 1])); } - function getClubs(int $page = 1, bool $admin = false, int $count = OPENVK_DEFAULT_PER_PAGE, bool $offset = false): \Traversable + public function getClubs(int $page = 1, bool $admin = false, int $count = OPENVK_DEFAULT_PER_PAGE, bool $offset = false): \Traversable { - if(!$offset) + if (!$offset) { $page = ($page - 1) * $count; + } - if($admin) { + if ($admin) { $id = $this->getId(); $query = "SELECT `id` FROM `groups` WHERE `owner` = ? UNION SELECT `club` as `id` FROM `group_coadmins` WHERE `user` = ?"; $query .= " LIMIT " . $count . " OFFSET " . $page; $sel = DatabaseConnection::i()->getConnection()->query($query, $id, $id); - foreach($sel as $target) { - $target = (new Clubs)->get($target->id); - if(!$target) continue; + foreach ($sel as $target) { + $target = (new Clubs())->get($target->id); + if (!$target) { + continue; + } yield $target; } } else { $sel = $this->getRecord()->related("subscriptions.follower")->limit($count, $page); - foreach($sel->where("model", "openvk\\Web\\Models\\Entities\\Club") as $target) { - $target = (new Clubs)->get($target->target); - if(!$target) continue; + foreach ($sel->where("model", "openvk\\Web\\Models\\Entities\\Club") as $target) { + $target = (new Clubs())->get($target->target); + if (!$target) { + continue; + } yield $target; } } } - function getClubCount(bool $admin = false): int + public function getClubCount(bool $admin = false): int { - if($admin) { + if ($admin) { $id = $this->getId(); $query = "SELECT COUNT(*) AS `cnt` FROM (SELECT `id` FROM `groups` WHERE `owner` = ? UNION SELECT `club` as `id` FROM `group_coadmins` WHERE `user` = ?) u0;"; @@ -698,63 +752,71 @@ class User extends RowModel } } - function getPinnedClubs(): \Traversable + public function getPinnedClubs(): \Traversable { - foreach($this->getRecord()->related("groups.owner")->where("owner_club_pinned", true) as $target) { - $target = (new Clubs)->get($target->id); - if(!$target) continue; + foreach ($this->getRecord()->related("groups.owner")->where("owner_club_pinned", true) as $target) { + $target = (new Clubs())->get($target->id); + if (!$target) { + continue; + } yield $target; } - foreach($this->getRecord()->related("group_coadmins.user")->where("club_pinned", true) as $target) { - $target = (new Clubs)->get($target->club); - if(!$target) continue; + foreach ($this->getRecord()->related("group_coadmins.user")->where("club_pinned", true) as $target) { + $target = (new Clubs())->get($target->club); + if (!$target) { + continue; + } yield $target; } } - function getPinnedClubCount(): int + public function getPinnedClubCount(): int { return sizeof($this->getRecord()->related("groups.owner")->where("owner_club_pinned", true)) + sizeof($this->getRecord()->related("group_coadmins.user")->where("club_pinned", true)); } - function isClubPinned(Club $club): bool + public function isClubPinned(Club $club): bool { - if($club->getOwner()->getId() === $this->getId()) + if ($club->getOwner()->getId() === $this->getId()) { return $club->isOwnerClubPinned(); + } $manager = $club->getManager($this); - if(!is_null($manager)) + if (!is_null($manager)) { return $manager->isClubPinned(); + } return false; } - function getMeetings(int $page = 1): \Traversable + public function getMeetings(int $page = 1): \Traversable { $sel = $this->getRecord()->related("event_turnouts.user")->page($page, OPENVK_DEFAULT_PER_PAGE); - foreach($sel as $target) { - $target = (new Clubs)->get($target->event); - if(!$target) continue; + foreach ($sel as $target) { + $target = (new Clubs())->get($target->event); + if (!$target) { + continue; + } yield $target; } } - function getMeetingCount(): int + public function getMeetingCount(): int { return sizeof($this->getRecord()->related("event_turnouts.user")); } - function getGifts(int $page = 1, ?int $perPage = NULL): \Traversable + public function getGifts(int $page = 1, ?int $perPage = null): \Traversable { $gifts = $this->getRecord()->related("gift_user_relations.receiver")->order("sent DESC")->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE); - foreach($gifts as $rel) { + foreach ($gifts as $rel) { yield (object) [ - "sender" => (new Users)->get($rel->sender), - "gift" => (new Gifts)->get($rel->gift), + "sender" => (new Users())->get($rel->sender), + "gift" => (new Gifts())->get($rel->gift), "caption" => $rel->comment, "anon" => $rel->anonymous, "sent" => new DateTime($rel->sent), @@ -762,44 +824,46 @@ class User extends RowModel } } - function getGiftCount(): int + public function getGiftCount(): int { return sizeof($this->getRecord()->related("gift_user_relations.receiver")); } - function get2faBackupCodes(): \Traversable + public function get2faBackupCodes(): \Traversable { $sel = $this->getRecord()->related("2fa_backup_codes.owner"); - foreach($sel as $target) + foreach ($sel as $target) { yield $target->code; + } } - function get2faBackupCodeCount(): int + public function get2faBackupCodeCount(): int { return sizeof($this->getRecord()->related("2fa_backup_codes.owner")); } - function generate2faBackupCodes(): void + public function generate2faBackupCodes(): void { $codes = []; - for($i = 0; $i < 10 - $this->get2faBackupCodeCount(); $i++) { + for ($i = 0; $i < 10 - $this->get2faBackupCodeCount(); $i++) { $codes[] = [ "owner" => $this->getId(), - "code" => random_int(10000000, 99999999) + "code" => random_int(10000000, 99999999), ]; } - if(sizeof($codes) > 0) + if (sizeof($codes) > 0) { DatabaseConnection::i()->getContext()->table("2fa_backup_codes")->insert($codes); + } } - function use2faBackupCode(int $code): bool + public function use2faBackupCode(int $code): bool { return (bool) $this->getRecord()->related("2fa_backup_codes.owner")->where("code", $code)->delete(); } - function getSubscriptionStatus(User $user): int + public function getSubscriptionStatus(User $user): int { $subbed = !is_null($this->getRecord()->related("subscriptions.follower")->where([ "model" => static::class, @@ -810,51 +874,57 @@ class User extends RowModel "follower" => $user->getId(), ])->fetch()); - if($subbed && $followed) return User::SUBSCRIPTION_MUTUAL; - if($subbed) return User::SUBSCRIPTION_INCOMING; - if($followed) return User::SUBSCRIPTION_OUTGOING; + if ($subbed && $followed) { + return User::SUBSCRIPTION_MUTUAL; + } + if ($subbed) { + return User::SUBSCRIPTION_INCOMING; + } + if ($followed) { + return User::SUBSCRIPTION_OUTGOING; + } return User::SUBSCRIPTION_ABSENT; } - function getNotificationsCount(bool $archived = false): int + public function getNotificationsCount(bool $archived = false): int { - return (new Notifications)->getNotificationCountByUser($this, $this->getNotificationOffset(), $archived); + return (new Notifications())->getNotificationCountByUser($this, $this->getNotificationOffset(), $archived); } - function getNotifications(int $page, bool $archived = false): \Traversable + public function getNotifications(int $page, bool $archived = false): \Traversable { - return (new Notifications)->getNotificationsByUser($this, $this->getNotificationOffset(), $archived, $page); + return (new Notifications())->getNotificationsByUser($this, $this->getNotificationOffset(), $archived, $page); } - function getPendingPhoneVerification(): ?ActiveRow + public function getPendingPhoneVerification(): ?ActiveRow { return $this->getRecord()->ref("number_verification", "id"); } - function getRefLinkId(): string + public function getRefLinkId(): string { $hash = hash_hmac("Snefru", (string) $this->getId(), CHANDLER_ROOT_CONF["security"]["secret"], true); return dechex($this->getId()) . " " . base64_encode($hash); } - function getNsfwTolerance(): int + public function getNsfwTolerance(): int { return $this->getRecord()->nsfw_tolerance; } - function isFemale(): bool + public function isFemale(): bool { return $this->getRecord()->sex == 1; } - function isNeutral(): bool + public function isNeutral(): bool { return (bool) $this->getRecord()->sex == 2; } - function getLocalizedPronouns(): string + public function getLocalizedPronouns(): string { switch ($this->getRecord()->sex) { case 0: @@ -866,35 +936,35 @@ class User extends RowModel } } - function getPronouns(): int + public function getPronouns(): int { return $this->getRecord()->sex; } - function isVerified(): bool + public function isVerified(): bool { return (bool) $this->getRecord()->verified; } - function isBanned(): bool + public function isBanned(): bool { return !is_null($this->getBanReason()); } - function isBannedInSupport(): bool + public function isBannedInSupport(): bool { return !is_null($this->getBanInSupportReason()); } - function isOnline(): bool + public function isOnline(): bool { return time() - $this->getRecord()->online <= 300; } - function getOnlinePlatform(bool $forAPI = false): ?string + public function getOnlinePlatform(bool $forAPI = false): ?string { $platform = $this->getRecord()->client_name; - if($forAPI) { + if ($forAPI) { switch ($platform) { case 'openvk_refresh_android': case 'openvk_legacy_android': @@ -905,16 +975,16 @@ class User extends RowModel case 'openvk_legacy_ios': return 'iphone'; break; - + case 'vika_touch': // кика хохотач ахахахаххахахахахах case 'vk4me': return 'mobile'; break; - case NULL: - return NULL; + case null: + return null; break; - + default: return 'api'; break; @@ -924,17 +994,17 @@ class User extends RowModel } } - function getOnlinePlatformDetails(): array + public function getOnlinePlatformDetails(): array { $clients = simplexml_load_file(OPENVK_ROOT . "/data/clients.xml"); - foreach($clients as $client) { - if($client['tag'] == $this->getOnlinePlatform()) { + foreach ($clients as $client) { + if ($client['tag'] == $this->getOnlinePlatform()) { return [ "tag" => $client['tag'], "name" => $client['name'], "url" => $client['url'], - "img" => $client['img'] + "img" => $client['img'], ]; break; } @@ -942,23 +1012,23 @@ class User extends RowModel return [ "tag" => $this->getOnlinePlatform(), - "name" => NULL, - "url" => NULL, - "img" => NULL + "name" => null, + "url" => null, + "img" => null, ]; } - function prefersNotToSeeRating(): bool + public function prefersNotToSeeRating(): bool { return !((bool) $this->getRecord()->show_rating); } - function hasPendingNumberChange(): bool + public function hasPendingNumberChange(): bool { return !is_null($this->getPendingPhoneVerification()); } - function gift(User $sender, Gift $gift, ?string $comment = NULL, bool $anonymous = false): void + public function gift(User $sender, Gift $gift, ?string $comment = null, bool $anonymous = false): void { DatabaseConnection::i()->getContext()->table("gift_user_relations")->insert([ "sender" => $sender->getId(), @@ -970,9 +1040,9 @@ class User extends RowModel ]); } - function ban(string $reason, bool $deleteSubscriptions = true, $unban_time = NULL, ?int $initiator = NULL): void + public function ban(string $reason, bool $deleteSubscriptions = true, $unban_time = null, ?int $initiator = null): void { - if($deleteSubscriptions) { + if ($deleteSubscriptions) { $subs = DatabaseConnection::i()->getContext()->table("subscriptions"); $subs = $subs->where( "follower = ? OR (target = ? AND model = ?)", @@ -984,7 +1054,7 @@ class User extends RowModel } $iat = time(); - $ban = new Ban; + $ban = new Ban(); $ban->setUser($this->getId()); $ban->setReason($reason); $ban->setInitiator($initiator); @@ -998,22 +1068,23 @@ class User extends RowModel $this->save(); } - function unban(int $removed_by): void + public function unban(int $removed_by): void { - $ban = (new Bans)->get((int) $this->getRawBanReason()); - if (!$ban || $ban->isOver()) + $ban = (new Bans())->get((int) $this->getRawBanReason()); + if (!$ban || $ban->isOver()) { return; + } $ban->setRemoved_Manually(true); $ban->setRemoved_By($removed_by); $ban->save(); - $this->setBlock_Reason(NULL); + $this->setBlock_Reason(null); // $user->setUnblock_time(NULL); $this->save(); } - function deactivate(?string $reason): void + public function deactivate(?string $reason): void { $this->setDeleted(1); $this->setDeact_Date(time() + (MONTH * 7)); @@ -1021,7 +1092,7 @@ class User extends RowModel $this->save(); } - function reactivate(): void + public function reactivate(): void { $this->setDeleted(0); $this->setDeact_Date(0); @@ -1029,19 +1100,23 @@ class User extends RowModel $this->save(); } - function getDeactivationDate(): DateTime + public function getDeactivationDate(): DateTime { return new DateTime($this->getRecord()->deact_date); } - - function verifyNumber(string $code): bool + + public function verifyNumber(string $code): bool { $ver = $this->getPendingPhoneVerification(); - if(!$ver) return false; + if (!$ver) { + return false; + } try { - if(sodium_memcmp((string) $ver->code, $code) === -1) return false; - } catch(\SodiumException $ex) { + if (sodium_memcmp((string) $ver->code, $code) === -1) { + return false; + } + } catch (\SodiumException $ex) { return false; } @@ -1056,33 +1131,34 @@ class User extends RowModel return true; } - function setFirst_Name(string $firstName): void + public function setFirst_Name(string $firstName): void { $firstName = mb_convert_case($firstName, MB_CASE_TITLE); - if(!preg_match('%^[\p{Lu}\p{Lo}]\p{Mn}?(?:[\p{L&}\p{Lo}]\p{Mn}?){1,64}$%u', $firstName)) - throw new InvalidUserNameException; + if (!preg_match('%^[\p{Lu}\p{Lo}]\p{Mn}?(?:[\p{L&}\p{Lo}]\p{Mn}?){1,64}$%u', $firstName)) { + throw new InvalidUserNameException(); + } $this->stateChanges("first_name", $firstName); } - function setLast_Name(string $lastName): void + public function setLast_Name(string $lastName): void { - if(!empty($lastName)) - { - $lastName = mb_convert_case($lastName, MB_CASE_TITLE); - if(!preg_match('%^[\p{Lu}\p{Lo}]\p{Mn}?([\p{L&}\p{Lo}]\p{Mn}?){1,64}(\-\g<1>+)?$%u', $lastName)) - throw new InvalidUserNameException; + if (!empty($lastName)) { + $lastName = mb_convert_case($lastName, MB_CASE_TITLE); + if (!preg_match('%^[\p{Lu}\p{Lo}]\p{Mn}?([\p{L&}\p{Lo}]\p{Mn}?){1,64}(\-\g<1>+)?$%u', $lastName)) { + throw new InvalidUserNameException(); + } } $this->stateChanges("last_name", $lastName); } - function setNsfwTolerance(int $tolerance): void + public function setNsfwTolerance(int $tolerance): void { $this->stateChanges("nsfw_tolerance", $tolerance); } - function setPrivacySetting(string $id, int $status): void + public function setPrivacySetting(string $id, int $status): void { $this->stateChanges("privacy", bmask($this->changes["privacy"] ?? $this->getRecord()->privacy, [ "length" => 2, @@ -1103,7 +1179,7 @@ class User extends RowModel ])->set($id, $status)->toInteger()); } - function setLeftMenuItemStatus(string $id, bool $status): void + public function setLeftMenuItemStatus(string $id, bool $status): void { $mask = bmask($this->changes["left_menu"] ?? $this->getRecord()->left_menu, [ "length" => 1, @@ -1125,36 +1201,42 @@ class User extends RowModel $this->stateChanges("left_menu", $mask); } - function setShortCode(?string $code = NULL, bool $force = false): ?bool + public function setShortCode(?string $code = null, bool $force = false): ?bool { - if(!is_null($code)) { - if(strlen($code) < OPENVK_ROOT_CONF["openvk"]["preferences"]["shortcodes"]["minLength"] && !$force) + if (!is_null($code)) { + if (strlen($code) < OPENVK_ROOT_CONF["openvk"]["preferences"]["shortcodes"]["minLength"] && !$force) { return false; - 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; - if(in_array($code, OPENVK_ROOT_CONF["openvk"]["preferences"]["shortcodes"]["forbiddenNames"])) + } + if (in_array($code, OPENVK_ROOT_CONF["openvk"]["preferences"]["shortcodes"]["forbiddenNames"])) { 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; + } $pClub = DatabaseConnection::i()->getContext()->table("groups")->where("shortcode", $code)->fetch(); - if(!is_null($pClub)) - return false; + if (!is_null($pClub)) { + return false; + } $pAlias = DatabaseConnection::i()->getContext()->table("aliases")->where("shortcode", $code)->fetch(); - if(!is_null($pAlias)) - return false; + if (!is_null($pAlias)) { + return false; + } } $this->stateChanges("shortcode", $code); return true; } - function setPhoneWithVerification(string $phone): string + public function setPhoneWithVerification(string $phone): string { $code = unpack("S", openssl_random_pseudo_bytes(2))[1]; - if($this->hasPendingNumberChange()) { + if ($this->hasPendingNumberChange()) { DatabaseConnection::i()->getContext() ->table("number_verification") ->where("user", $this->getId()) @@ -1171,7 +1253,7 @@ class User extends RowModel # KABOBSQL temporary fix # Tuesday, the 7th of January 2020 @ 22:43 : implementing quick fix to this problem and monitoring # NOTICE: this is an ongoing conversation, add your comments just above this line. Thanks! - function setOnline(int $time): bool + public function setOnline(int $time): bool { $this->stateChanges("shortcode", $this->getRecord()->shortcode); #fix KABOBSQL $this->stateChanges("online", $time); @@ -1179,7 +1261,7 @@ class User extends RowModel return true; } - function updOnline(string $platform): bool + public function updOnline(string $platform): bool { $this->setOnline(time()); $this->setClient_name($platform); @@ -1188,47 +1270,50 @@ class User extends RowModel return true; } - function changeEmail(string $email): void + public function changeEmail(string $email): void { DatabaseConnection::i()->getContext()->table("ChandlerUsers") ->where("id", $this->getChandlerUser()->getId())->update([ - "login" => $email + "login" => $email, ]); $this->stateChanges("email", $email); $this->save(); } - function adminNotify(string $message): bool + public function adminNotify(string $message): bool { $admId = (int) OPENVK_ROOT_CONF["openvk"]["preferences"]["support"]["adminAccount"]; - if(!$admId) + if (!$admId) { return false; - else if(is_null($admin = (new Users)->get($admId))) + } elseif (is_null($admin = (new Users())->get($admId))) { return false; + } $cor = new Correspondence($admin, $this); - $msg = new Message; + $msg = new Message(); $msg->setContent($message); $cor->sendMessage($msg, true); return true; } - function isDeleted(): bool + public function isDeleted(): bool { - if($this->getRecord()->deleted == 1) - return TRUE; - else - return FALSE; + if ($this->getRecord()->deleted == 1) { + return true; + } else { + return false; + } } - function isDeactivated(): bool + public function isDeactivated(): bool { - if($this->getDeactivationDate()->timestamp() > time()) - return TRUE; - else - return FALSE; + if ($this->getDeactivationDate()->timestamp() > time()) { + return true; + } else { + return false; + } } /** @@ -1236,7 +1321,7 @@ class User extends RowModel * 1 - Incognito online status * 2 - Page of a dead person */ - function onlineStatus(): int + public function onlineStatus(): int { switch ($this->getRecord()->online) { case 1: @@ -1253,57 +1338,69 @@ class User extends RowModel } } - function getWebsite(): ?string - { - return $this->getRecord()->website; - } + public function getWebsite(): ?string + { + return $this->getRecord()->website; + } # ты устрица - function isActivated(): bool + public function isActivated(): bool { return (bool) $this->getRecord()->activated; } - function isAdmin(): bool + public function isAdmin(): bool { - return $this->getChandlerUser()->can("access")->model("admin")->whichBelongsTo(NULL); + return $this->getChandlerUser()->can("access")->model("admin")->whichBelongsTo(null); } - function isDead(): bool + public function isDead(): bool { return $this->onlineStatus() == 2; } - - function getUnbanTime(): ?string + + public function getUnbanTime(): ?string { - $ban = (new Bans)->get((int) $this->getRecord()->block_reason); - if (!$ban || $ban->isOver() || $ban->isPermanent()) return null; - if ($this->canUnbanThemself()) return tr("today"); + $ban = (new Bans())->get((int) $this->getRecord()->block_reason); + if (!$ban || $ban->isOver() || $ban->isPermanent()) { + return null; + } + if ($this->canUnbanThemself()) { + return tr("today"); + } return date('d.m.Y', $ban->getEndTime()); } - function canUnbanThemself(): bool + public function canUnbanThemself(): bool { - if (!$this->isBanned()) + if (!$this->isBanned()) { return false; + } - $ban = (new Bans)->get((int) $this->getRecord()->block_reason); - if (!$ban || $ban->isOver() || $ban->isPermanent()) return false; + $ban = (new Bans())->get((int) $this->getRecord()->block_reason); + if (!$ban || $ban->isOver() || $ban->isPermanent()) { + return false; + } return $ban->getEndTime() <= time() && !$ban->isPermanent(); } - function getNewBanTime() + public function getNewBanTime() { - $bans = iterator_to_array((new Bans)->getByUser($this->getid())); - if (!$bans || count($bans) === 0) + $bans = iterator_to_array((new Bans())->getByUser($this->getid())); + if (!$bans || count($bans) === 0) { return 0; + } $last_ban = end($bans); - if (!$last_ban) return 0; + if (!$last_ban) { + return 0; + } - if ($last_ban->isPermanent()) return "0"; + if ($last_ban->isPermanent()) { + return "0"; + } $values = [0, 3600, 7200, 86400, 172800, 604800, 1209600, 3024000, 9072000]; $response = 0; @@ -1311,44 +1408,48 @@ class User extends RowModel foreach ($values as $value) { $i++; - if ($last_ban->getTime() === 0 && $value === 0) continue; + if ($last_ban->getTime() === 0 && $value === 0) { + continue; + } if ($last_ban->getTime() < $value) { $response = $value; break; - } else if ($last_ban->getTime() >= $value) { - if ($i < count($values)) continue; + } elseif ($last_ban->getTime() >= $value) { + if ($i < count($values)) { + continue; + } $response = "0"; break; } } return $response; } - - function getProfileType(): int + + public function getProfileType(): int { # 0 — открытый профиль, 1 — закрытый return $this->getRecord()->profile_type; } - function canBeViewedBy(?User $user = NULL, bool $blacklist_check = true): bool + public function canBeViewedBy(?User $user = null, bool $blacklist_check = true): bool { - if(!is_null($user)) { - if($this->getId() == $user->getId()) { + if (!is_null($user)) { + if ($this->getId() == $user->getId()) { return true; } - if($user->isAdmin() && !(OPENVK_ROOT_CONF['openvk']['preferences']['blacklists']['applyToAdmins'] ?? true)) { + if ($user->isAdmin() && !(OPENVK_ROOT_CONF['openvk']['preferences']['blacklists']['applyToAdmins'] ?? true)) { return true; } - if($blacklist_check && ($this->isBlacklistedBy($user) || $user->isBlacklistedBy($this))) { + if ($blacklist_check && ($this->isBlacklistedBy($user) || $user->isBlacklistedBy($this))) { return false; } - if($this->getProfileType() == 0) { + if ($this->getProfileType() == 0) { return true; } else { - if($user->getSubscriptionStatus($this) == User::SUBSCRIPTION_MUTUAL) { + if ($user->getSubscriptionStatus($this) == User::SUBSCRIPTION_MUTUAL) { return true; } else { return false; @@ -1356,8 +1457,8 @@ class User extends RowModel } } else { - if($this->getProfileType() == 0) { - if($this->getPrivacySetting("page.read") == 3) { + if ($this->getProfileType() == 0) { + if ($this->getPrivacySetting("page.read") == 3) { return true; } else { return false; @@ -1370,27 +1471,27 @@ class User extends RowModel return true; } - function isClosed(): bool + public function isClosed(): bool { return (bool) $this->getProfileType(); } - function isHideFromGlobalFeedEnabled(): bool + public function isHideFromGlobalFeedEnabled(): bool { return $this->isClosed(); } - - function getRealId() + + public function getRealId() { return $this->getId(); } - function isPrivateLikes(): bool + public function isPrivateLikes(): bool { return $this->getPrivacySetting("likes.read") == User::PRIVACY_NO_ONE; } - function toVkApiStruct(?User $user = NULL, string $fields = ''): object + public function toVkApiStruct(?User $user = null, string $fields = ''): object { $res = (object) []; @@ -1400,20 +1501,22 @@ class User extends RowModel $res->deactivated = $this->isDeactivated(); $res->is_closed = $this->isClosed(); - if(!is_null($user)) - $res->can_access_closed = (bool)$this->canBeViewedBy($user); + if (!is_null($user)) { + $res->can_access_closed = (bool) $this->canBeViewedBy($user); + } - if(!is_array($fields)) + if (!is_array($fields)) { $fields = explode(',', $fields); - + } + $avatar_photo = $this->getAvatarPhoto(); - foreach($fields as $field) { - switch($field) { + foreach ($fields as $field) { + switch ($field) { case 'is_dead': $res->is_dead = $this->isDead(); break; case 'verified': - $res->verified = (int)$this->isVerified(); + $res->verified = (int) $this->isVerified(); break; case 'sex': $res->sex = $this->isFemale() ? 1 : ($this->isNeutral() ? 0 : 2); @@ -1431,7 +1534,7 @@ class User extends RowModel $res->photo_max = $this->getAvatarUrl('original', $avatar_photo); break; case 'photo_id': - $res->photo_id = $avatar_photo ? $avatar_photo->getPrettyId() : NULL; + $res->photo_id = $avatar_photo ? $avatar_photo->getPrettyId() : null; break; case 'background': $res->background = $this->getBackDropPictureURLs(); @@ -1449,24 +1552,24 @@ class User extends RowModel $res->status = $this->getStatus(); break; case 'screen_name': - $res->screen_name = $this->getShortCode() ?? "id".$this->getId(); + $res->screen_name = $this->getShortCode() ?? "id" . $this->getId(); break; case 'real_id': $res->real_id = $this->getRealId(); break; case "blacklisted_by_me": - if(!$user) { + if (!$user) { continue; } - $res->blacklisted_by_me = (int)$this->isBlacklistedBy($user); + $res->blacklisted_by_me = (int) $this->isBlacklistedBy($user); break; case "blacklisted": - if(!$user) { + if (!$user) { continue; } - - $res->blacklisted = (int)$user->isBlacklistedBy($this); + + $res->blacklisted = (int) $user->isBlacklistedBy($this); break; case "games": $res->games = $this->getFavoriteGames(); @@ -1476,65 +1579,70 @@ class User extends RowModel return $res; } - - function getAudiosCollectionSize() + + public function getAudiosCollectionSize() { - return (new \openvk\Web\Models\Repositories\Audios)->getUserCollectionSize($this); + return (new \openvk\Web\Models\Repositories\Audios())->getUserCollectionSize($this); } - function getBroadcastList(string $filter = "friends", bool $shuffle = false) + public function getBroadcastList(string $filter = "friends", bool $shuffle = false) { $dbContext = DatabaseConnection::i()->getContext(); $entityIds = []; $query = $dbContext->table("subscriptions")->where("follower", $this->getRealId()); - if($filter != "all") + if ($filter != "all") { $query = $query->where("model = ?", "openvk\\Web\\Models\\Entities\\" . ($filter == "groups" ? "Club" : "User")); + } - foreach($query as $_rel) { + foreach ($query as $_rel) { $entityIds[] = $_rel->model == "openvk\\Web\\Models\\Entities\\Club" ? $_rel->target * -1 : $_rel->target; } - if($shuffle) { + if ($shuffle) { $shuffleSeed = openssl_random_pseudo_bytes(6); $shuffleSeed = hexdec(bin2hex($shuffleSeed)); - + $entityIds = knuth_shuffle($entityIds, $shuffleSeed); } - + $entityIds = array_slice($entityIds, 0, 10); $returnArr = []; - - foreach($entityIds as $id) { - $entit = $id > 0 ? (new Users)->get($id) : (new Clubs)->get(abs($id)); - if($id > 0 && $entit->isDeleted()) continue; + foreach ($entityIds as $id) { + $entit = $id > 0 ? (new Users())->get($id) : (new Clubs())->get(abs($id)); + + if ($id > 0 && $entit->isDeleted()) { + continue; + } $returnArr[] = $entit; } return $returnArr; } - function getIgnoredSources(int $offset = 0, int $limit = 10, bool $onlyIds = false) + public function getIgnoredSources(int $offset = 0, int $limit = 10, bool $onlyIds = false) { $sources = DatabaseConnection::i()->getContext()->table("ignored_sources")->where("owner", $this->getId())->limit($limit, $offset)->order('id DESC'); $output_array = []; - foreach($sources as $source) { - if($onlyIds) { - $output_array[] = (int)$source->source; + foreach ($sources as $source) { + if ($onlyIds) { + $output_array[] = (int) $source->source; } else { - $ignored_source_model = NULL; - $ignored_source_id = (int)$source->source; + $ignored_source_model = null; + $ignored_source_id = (int) $source->source; - if($ignored_source_id > 0) - $ignored_source_model = (new Users)->get($ignored_source_id); - else - $ignored_source_model = (new Clubs)->get(abs($ignored_source_id)); - - if(!$ignored_source_model) + if ($ignored_source_id > 0) { + $ignored_source_model = (new Users())->get($ignored_source_id); + } else { + $ignored_source_model = (new Clubs())->get(abs($ignored_source_id)); + } + + if (!$ignored_source_model) { continue; + } $output_array[] = $ignored_source_model; } @@ -1543,15 +1651,16 @@ class User extends RowModel return $output_array; } - function getIgnoredSourcesCount() + public function getIgnoredSourcesCount() { return DatabaseConnection::i()->getContext()->table("ignored_sources")->where("owner", $this->getId())->count(); } - function isBlacklistedBy(?User $user = NULL): bool + public function isBlacklistedBy(?User $user = null): bool { - if(!$user) + if (!$user) { return false; + } $ctx = DatabaseConnection::i()->getContext(); $data = [ @@ -1563,8 +1672,8 @@ class User extends RowModel return $sub->count() > 0; } - function addToBlacklist(?User $user) - { + public function addToBlacklist(?User $user) + { DatabaseConnection::i()->getContext()->table("blacklist_relations")->insert([ "author" => $this->getRealId(), "target" => $user->getRealId(), @@ -1582,30 +1691,31 @@ class User extends RowModel "model" => static::class, "target" => $user->getId(), ])->delete(); - + return true; } - function removeFromBlacklist(?User $user): bool + public function removeFromBlacklist(?User $user): bool { DatabaseConnection::i()->getContext()->table("blacklist_relations")->where([ "author" => $this->getRealId(), "target" => $user->getRealId(), ])->delete(); - + return true; } - function getBlacklist(int $offset = 0, int $limit = 10) + public function getBlacklist(int $offset = 0, int $limit = 10) { $sources = DatabaseConnection::i()->getContext()->table("blacklist_relations")->where("author", $this->getId())->limit($limit, $offset)->order('created ASC'); $output_array = []; - foreach($sources as $source) { - $entity_id = (int)$source->target ; - $entity = (new Users)->get($entity_id); - if(!$entity) + foreach ($sources as $source) { + $entity_id = (int) $source->target ; + $entity = (new Users())->get($entity_id); + if (!$entity) { continue; + } $output_array[] = $entity; } @@ -1613,13 +1723,8 @@ class User extends RowModel return $output_array; } - function getBlacklistSize() + public function getBlacklistSize() { return DatabaseConnection::i()->getContext()->table("blacklist_relations")->where("author", $this->getId())->count(); } - - use Traits\TBackDrops; - use Traits\TSubscribable; - use Traits\TAudioStatuses; - use Traits\TIgnorable; } diff --git a/Web/Models/Entities/UserInfoEntities/AdditionalField.php b/Web/Models/Entities/UserInfoEntities/AdditionalField.php index 47c69de3..7ae115b0 100644 --- a/Web/Models/Entities/UserInfoEntities/AdditionalField.php +++ b/Web/Models/Entities/UserInfoEntities/AdditionalField.php @@ -1,5 +1,9 @@ -getRecord()->owner; } - function getName(bool $tr = true): string + public function getName(bool $tr = true): string { $orig_name = $this->getRecord()->name; $name = $orig_name; - if($tr && $name[0] === "_") + if ($tr && $name[0] === "_") { $name = tr("custom_field_" . substr($name, 1)); + } - if(str_contains($name, "custom_field")) + if (str_contains($name, "custom_field")) { return $orig_name; + } return $name; } - function getContent(): string + public function getContent(): string { return $this->getRecord()->text; } - function getPlace(): string + public function getPlace(): string { - switch($this->getRecord()->place) { + switch ($this->getRecord()->place) { case AdditionalField::PLACE_CONTACTS: return "contact"; case AdditionalField::PLACE_INTERESTS: @@ -46,47 +52,48 @@ class AdditionalField extends RowModel return "contact"; } - function isContact(): bool + public function isContact(): bool { return $this->getRecord()->place == AdditionalField::PLACE_CONTACTS; } - function toVkApiStruct(): object + public function toVkApiStruct(): object { return (object) [ "type" => $this->getRecord()->place, "name" => $this->getName(), - "text" => $this->getContent() + "text" => $this->getContent(), ]; } - static function getById(int $id) + public static function getById(int $id) { $ctx = DatabaseConnection::i()->getContext(); $entry = $ctx->table("additional_fields")->where("id", $id)->fetch(); - if(!$entry) - return NULL; - + if (!$entry) { + return null; + } + return new AdditionalField($entry); } - static function getByOwner(int $owner): \Traversable + public static function getByOwner(int $owner): \Traversable { $ctx = DatabaseConnection::i()->getContext(); $entries = $ctx->table("additional_fields")->where("owner", $owner); - foreach($entries as $entry) { + foreach ($entries as $entry) { yield new AdditionalField($entry); } } - static function getCountByOwner(int $owner): \Traversable + public static function getCountByOwner(int $owner): \Traversable { return DatabaseConnection::i()->getContext()->table("additional_fields")->where("owner", $owner)->count(); } - static function resetByOwner(int $owner): bool + public static function resetByOwner(int $owner): bool { DatabaseConnection::i()->getContext()->table("additional_fields")->where("owner", $owner)->delete(); diff --git a/Web/Models/Entities/Video.php b/Web/Models/Entities/Video.php index d134645e..b8a9fcca 100644 --- a/Web/Models/Entities/Video.php +++ b/Web/Models/Entities/Video.php @@ -1,5 +1,9 @@ -execute($error); - if($error !== 0) + if ($error !== 0) { throw new \DomainException("$filename is not a valid video file"); - else if(empty($streams) || ctype_space($streams)) + } elseif (empty($streams) || ctype_space($streams)) { throw new \DomainException("$filename does not contain any video 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 video streams"); - + } + $length = 0; - foreach($durations[1] as $duration) { + foreach ($durations[1] as $duration) { $duration = floatval($duration); - if($duration < 1.0) + if ($duration < 1.0) { throw new \DomainException("$filename does not contain any meaningful video streams"); - else + } else { $length = max($length, $duration); + } } $this->stateChanges("length", (int) round($length, 0, PHP_ROUND_HALF_EVEN)); preg_match('%width=([0-9\.]++)%', $streams, $width); preg_match('%height=([0-9\.]++)%', $streams, $height); - if(!empty($width) && !empty($height)) { + if (!empty($width) && !empty($height)) { $this->stateChanges("width", $width[1]); $this->stateChanges("height", $height[1]); } - + try { - if(!is_dir($dirId = dirname($this->pathFromHash($hash)))) + if (!is_dir($dirId = dirname($this->pathFromHash($hash)))) { mkdir($dirId); - + } + $dir = $this->getBaseDir(); $ext = Shell::isPowershell() ? "ps1" : "sh"; $cmd = Shell::isPowershell() ? "powershell" : "bash"; Shell::$cmd(__DIR__ . "/../shell/processVideo.$ext", OPENVK_ROOT, $filename, $dir, $hash)->start(); #async :DDD - } catch(ShellUnavailableException $suex) { + } catch (ShellUnavailableException $suex) { exit(OPENVK_ROOT_CONF["openvk"]["debug"] ? "Shell is unavailable" : VIDEOS_FRIENDLY_ERROR); - } catch(UnknownCommandException $ucex) { + } catch (UnknownCommandException $ucex) { exit(OPENVK_ROOT_CONF["openvk"]["debug"] ? "bash is not installed" : VIDEOS_FRIENDLY_ERROR); } - + usleep(200100); return true; } protected function checkIfFileIsProcessed(): bool { - if($this->getType() != Video::TYPE_DIRECT) + if ($this->getType() != Video::TYPE_DIRECT) { return true; + } - if(!file_exists($this->getFileName())) { - if((time() - $this->getRecord()->last_checked) > 3600) { + if (!file_exists($this->getFileName())) { + if ((time() - $this->getRecord()->last_checked) > 3600) { # TODO notify that video processor is probably dead } @@ -86,37 +96,41 @@ class Video extends Media return true; } - function getName(): string + public function getName(): string { return $this->getRecord()->name; } - - function getType(): int + + public function getType(): int { - if(!is_null($this->getRecord()->hash)) + if (!is_null($this->getRecord()->hash)) { return Video::TYPE_DIRECT; - else if(!is_null($this->getRecord()->link)) + } elseif (!is_null($this->getRecord()->link)) { return Video::TYPE_EMBED; + } } - - function getVideoDriver(): ?VideoDriver + + public function getVideoDriver(): ?VideoDriver { - if($this->getType() !== Video::TYPE_EMBED) - return NULL; - + if ($this->getType() !== Video::TYPE_EMBED) { + return null; + } + [$videoDriver, $pointer] = explode(":", $this->getRecord()->link); $videoDriver = "openvk\\Web\\Models\\VideoDrivers\\$videoDriver" . "VideoDriver"; - if(!class_exists($videoDriver)) - return NULL; - + if (!class_exists($videoDriver)) { + return null; + } + return new $videoDriver($pointer); } - - function getThumbnailURL(): string + + public function getThumbnailURL(): string { - if($this->getType() === Video::TYPE_DIRECT) { - if(!$this->isProcessed()) + if ($this->getType() === Video::TYPE_DIRECT) { + if (!$this->isProcessed()) { return "/assets/packages/static/openvk/video/rendering.apng"; + } return preg_replace("%\.[A-z0-9]++$%", ".gif", $this->getURL()); } else { @@ -124,16 +138,16 @@ class Video extends Media } } - function getOwnerVideo(): int + public function getOwnerVideo(): int { return $this->getRecord()->owner; } - function getApiStructure(?User $user = NULL): object + public function getApiStructure(?User $user = null): object { $fromYoutube = $this->getType() == Video::TYPE_EMBED; $dimensions = $this->getDimensions(); - $res = (object)[ + $res = (object) [ "type" => "video", "video" => [ "can_comment" => 1, @@ -151,8 +165,8 @@ class Video extends Media "url" => $this->getThumbnailURL(), "width" => 320, "height" => 240, - "with_padding" => 1 - ] + "with_padding" => 1, + ], ], "width" => $dimensions ? $dimensions[0] : 640, "height" => $dimensions ? $dimensions[1] : 480, @@ -163,9 +177,9 @@ class Video extends Media "is_favorite" => false, "player" => !$fromYoutube ? $this->getURL() : $this->getVideoDriver()->getURL(), "files" => !$fromYoutube ? [ - "mp4_480" => $this->getURL() - ] : NULL, - "platform" => $fromYoutube ? "youtube" : NULL, + "mp4_480" => $this->getURL(), + ] : null, + "platform" => $fromYoutube ? "youtube" : null, "added" => 0, "repeat" => 0, "type" => "video", @@ -173,62 +187,64 @@ class Video extends Media "is_processed" => $this->isProcessed(), "reposts" => [ "count" => 0, - "user_reposted" => 0 - ] - ] + "user_reposted" => 0, + ], + ], ]; - if(!is_null($user)) { + if (!is_null($user)) { $res->video["likes"] = [ "count" => $this->getLikesCount(), - "user_likes" => $this->hasLikeFrom($user) + "user_likes" => $this->hasLikeFrom($user), ]; } return $res; } - - function toVkApiStruct(?User $user): object + + public function toVkApiStruct(?User $user): object { return $this->getApiStructure($user); } - function setLink(string $link): string + public function setLink(string $link): string { - if(preg_match(file_get_contents(__DIR__ . "/../VideoDrivers/regex/youtube.txt"), $link, $matches)) { + if (preg_match(file_get_contents(__DIR__ . "/../VideoDrivers/regex/youtube.txt"), $link, $matches)) { $pointer = "YouTube:$matches[1]"; - /*} else if(preg_match(file_get_contents(__DIR__ . "/../VideoDrivers/regex/vimeo.txt"), $link, $matches)) { - $pointer = "Vimeo:$matches[1]";*/ + /*} else if(preg_match(file_get_contents(__DIR__ . "/../VideoDrivers/regex/vimeo.txt"), $link, $matches)) { + $pointer = "Vimeo:$matches[1]";*/ } else { throw new ISE("Invalid link"); } - + $this->stateChanges("link", $pointer); - + return $pointer; } - function isDeleted(): bool + public function isDeleted(): bool { - if ($this->getRecord()->deleted == 1) - return TRUE; - else - return FALSE; + if ($this->getRecord()->deleted == 1) { + return true; + } else { + return false; + } } - function deleteVideo(): void + public function deleteVideo(): void { $this->setDeleted(1); $this->unwire(); $this->save(); } - - static function fastMake(int $owner, string $name = "Unnamed Video.ogv", string $description = "", array $file, bool $unlisted = true, bool $anon = false): Video - { - if(OPENVK_ROOT_CONF['openvk']['preferences']['videos']['disableUploading']) - exit(VIDEOS_FRIENDLY_ERROR); - $video = new Video; + public static function fastMake(int $owner, string $name = "Unnamed Video.ogv", string $description = "", array $file, bool $unlisted = true, bool $anon = false): Video + { + if (OPENVK_ROOT_CONF['openvk']['preferences']['videos']['disableUploading']) { + exit(VIDEOS_FRIENDLY_ERROR); + } + + $video = new Video(); $video->setOwner($owner); $video->setName(ovk_proc_strtr($name, 61)); $video->setDescription(ovk_proc_strtr($description, 300)); @@ -237,40 +253,41 @@ class Video extends Media $video->setFile($file); $video->setUnlisted($unlisted); $video->save(); - + return $video; } - function fillDimensions() + public function fillDimensions() { $hash = $this->getRecord()->hash; $path = $this->pathFromHash($hash); - if(!file_exists($path)) { + if (!file_exists($path)) { $this->stateChanges("width", 0); $this->stateChanges("height", 0); $this->stateChanges("length", 0); $this->save(); return false; } - + $streams = Shell::ffprobe("-i", $path, "-show_streams", "-select_streams v", "-loglevel error")->execute($error); $durations = []; preg_match_all('%duration=([0-9\.]++)%', $streams, $durations); - + $length = 0; - foreach($durations[1] as $duration) { + foreach ($durations[1] as $duration) { $duration = floatval($duration); - if($duration < 1.0) + if ($duration < 1.0) { continue; - else + } else { $length = max($length, $duration); + } } $this->stateChanges("length", (int) round($length, 0, PHP_ROUND_HALF_EVEN)); - + preg_match('%width=([0-9\.]++)%', $streams, $width); preg_match('%height=([0-9\.]++)%', $streams, $height); - if(!empty($width) && !empty($height)) { + if (!empty($width) && !empty($height)) { $this->stateChanges("width", $width[1]); $this->stateChanges("height", $height[1]); } @@ -280,26 +297,32 @@ class Video extends Media return true; } - function getDimensions() + public function getDimensions() { - if($this->getType() == Video::TYPE_EMBED) return [320, 180]; + if ($this->getType() == Video::TYPE_EMBED) { + return [320, 180]; + } $width = $this->getRecord()->width; $height = $this->getRecord()->height; - - if(!$width) return NULL; - return $width != 0 ? [$width, $height] : NULL; + + if (!$width) { + return null; + } + return $width != 0 ? [$width, $height] : null; } - function getLength() + public function getLength() { return $this->getRecord()->length; } - function getFormattedLength(): string + public function getFormattedLength(): string { $len = $this->getLength(); - if(!$len) return "00:00"; + if (!$len) { + return "00:00"; + } $mins = floor($len / 60); $secs = $len - ($mins * 60); return ( @@ -308,37 +331,37 @@ class Video extends Media str_pad((string) $secs, 2, "0", STR_PAD_LEFT) ); } - - function getPageURL(): string + + public function getPageURL(): string { - return "/video".$this->getPrettyId(); + return "/video" . $this->getPrettyId(); } - - 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; } - if(get_class($this->getOwner()) == "openvk\\Web\\Models\\Entities\\User") { + if (get_class($this->getOwner()) == "openvk\\Web\\Models\\Entities\\User") { return $this->getOwner()->canBeViewedBy($user) && $this->getOwner()->getPrivacyPermission('videos.read', $user); } else { # Groups doesn't have videos but ok return $this->getOwner()->canBeViewedBy($user); } } - - function toNotifApiStruct() + + public function toNotifApiStruct() { $fromYoutube = $this->getType() == Video::TYPE_EMBED; - $res = (object)[]; - + $res = (object) []; + $res->id = $this->getVirtualId(); $res->owner_id = $this->getOwner()->getId(); $res->title = $this->getName(); $res->description = $this->getDescription(); $res->duration = $this->getLength(); - $res->link = "/video".$this->getOwner()->getId()."_".$this->getVirtualId(); + $res->link = "/video" . $this->getOwner()->getId() . "_" . $this->getVirtualId(); $res->image = $this->getThumbnailURL(); $res->date = $this->getPublicationTime()->timestamp(); $res->views = 0; diff --git a/Web/Models/Entities/VideoAlbum.php b/Web/Models/Entities/VideoAlbum.php index 578ecf3d..401b556d 100644 --- a/Web/Models/Entities/VideoAlbum.php +++ b/Web/Models/Entities/VideoAlbum.php @@ -1,43 +1,49 @@ - "_added_album", 32 => "_uploaded_album", ]; - - function getCoverURL(): ?string + + public function getCoverURL(): ?string { $cover = $this->getCoverVideo(); - if(!$cover) + if (!$cover) { return "/assets/packages/static/openvk/img/camera_200.png"; - + } + return $cover->getThumbnailURL(); } - - function getCoverVideo(): ?Photo + + public function getCoverVideo(): ?Photo { $cover = $this->getRecord()->cover_video; - if(!$cover) { + if (!$cover) { $vids = iterator_to_array($this->fetch(1, 1)); - $vid = $vids[0] ?? NULL; - if(!$vid || $vid->isDeleted()) - return NULL; - else + $vid = $vids[0] ?? null; + if (!$vid || $vid->isDeleted()) { + return null; + } else { return $vid; + } } - - return (new Videos)->get($cover); + + return (new Videos())->get($cover); } } diff --git a/Web/Models/Entities/Voucher.php b/Web/Models/Entities/Voucher.php index 6469dddc..fe988e73 100644 --- a/Web/Models/Entities/Voucher.php +++ b/Web/Models/Entities/Voucher.php @@ -1,5 +1,9 @@ -getRecord()->coins; } - - function getRating(): int + + public function getRating(): int { return $this->getRecord()->rating; } - - function getToken(): string + + public function getToken(): string { return $this->getRecord()->token; } - - function getFormattedToken(): string + + public function getFormattedToken(): string { - $fmtTok = ""; + $fmtTok = ""; $token = $this->getRecord()->token; - foreach(array_chunk(str_split($token), 6) as $chunk) + foreach (array_chunk(str_split($token), 6) as $chunk) { $fmtTok .= implode("", $chunk) . "-"; - + } + return substr($fmtTok, 0, -1); } - - function getRemainingUsages(): float + + public function getRemainingUsages(): float { return (float) ($this->getRecord()->usages_left ?? INF); } - - function getUsers(int $page = -1, ?int $perPage = NULL): \Traversable + + public function getUsers(int $page = -1, ?int $perPage = null): \Traversable { $relations = $this->getRecord()->related("voucher_users.voucher"); - if($page !== -1) + if ($page !== -1) { $relations = $relations->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE); - - foreach($relations as $relation) - yield (new Users)->get($relation->user); + } + + foreach ($relations as $relation) { + yield (new Users())->get($relation->user); + } } - - function isExpired(): bool + + public function isExpired(): bool { return $this->getRemainingUsages() < 1; } - - function wasUsedBy(User $user): bool + + public function wasUsedBy(User $user): bool { $record = $this->getRecord()->related("voucher_users.voucher")->where("user", $user->getId()); - + return sizeof($record) > 0; } - - function willUse(User $user): bool + + public function willUse(User $user): bool { - if($this->wasUsedBy($user)) + if ($this->wasUsedBy($user)) { return false; - - if($this->isExpired()) + } + + if ($this->isExpired()) { return false; - + } + $this->setRemainingUsages($this->getRemainingUsages() - 1); DB::i()->getContext()->table("voucher_users")->insert([ "voucher" => $this->getId(), "user" => $user->getId(), ]); - + return true; } - - function setRemainingUsages(float $usages): void + + public function setRemainingUsages(float $usages): void { - $this->stateChanges("usages_left", $usages === INF ? NULL : ((int) $usages)); + $this->stateChanges("usages_left", $usages === INF ? null : ((int) $usages)); $this->save(); } } diff --git a/Web/Models/Exceptions/AlreadyVotedException.php b/Web/Models/Exceptions/AlreadyVotedException.php index 08363b9a..58cfa0df 100644 --- a/Web/Models/Exceptions/AlreadyVotedException.php +++ b/Web/Models/Exceptions/AlreadyVotedException.php @@ -1,7 +1,7 @@ -get((int) $id); - if(!$token) - return NULL; - else if($token->getSecret() !== $secret) - return NULL; - else if($token->isRevoked() && !$withRevoked) - return NULL; - + if (!$token) { + return null; + } elseif ($token->getSecret() !== $secret) { + return null; + } elseif ($token->isRevoked() && !$withRevoked) { + return null; + } + return $token; } - - function getStaleByUser(int $userId, string $platform, bool $withRevoked = false): ?APIToken + + public function getStaleByUser(int $userId, string $platform, bool $withRevoked = false): ?APIToken { return $this->toEntity($this->table->where([ 'user' => $userId, diff --git a/Web/Models/Repositories/Albums.php b/Web/Models/Repositories/Albums.php index f99848c4..f8799b8d 100644 --- a/Web/Models/Repositories/Albums.php +++ b/Web/Models/Repositories/Albums.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->albums = $this->context->table("albums"); } - + private function toAlbum(?ActiveRow $ar): ?Album { - return is_null($ar) ? NULL : new Album($ar); + return is_null($ar) ? null : new Album($ar); } - + private function getSpecialConditions(int $id, int $type): array { return [ @@ -31,106 +35,108 @@ class Albums "special_type" => $type, ]; } - - function get(int $id): ?Album + + public function get(int $id): ?Album { return $this->toAlbum($this->albums->get($id)); } - - function getUserAlbums(User $user, int $page = 1, ?int $perPage = NULL): \Traversable + + public function getUserAlbums(User $user, int $page = 1, ?int $perPage = null): \Traversable { - $perPage = $perPage ?? OPENVK_DEFAULT_PER_PAGE; + $perPage ??= OPENVK_DEFAULT_PER_PAGE; $albums = $this->albums->where("owner", $user->getId())->where("deleted", false); - foreach($albums->page($page, $perPage) as $album) + foreach ($albums->page($page, $perPage) as $album) { yield new Album($album); + } } - - function getUserAlbumsCount(User $user): int + + public function getUserAlbumsCount(User $user): int { $albums = $this->albums->where("owner", $user->getId())->where("deleted", false); return sizeof($albums); } - - function getClubAlbums(Club $club, int $page = 1, ?int $perPage = NULL): \Traversable + + public function getClubAlbums(Club $club, int $page = 1, ?int $perPage = null): \Traversable { - $perPage = $perPage ?? OPENVK_DEFAULT_PER_PAGE; - $albums = $this->albums->where("owner", $club->getId() * -1)->where("special_type", 0)->where("deleted", false); - foreach($albums->page($page, $perPage) as $album) + $perPage ??= OPENVK_DEFAULT_PER_PAGE; + $albums = $this->albums->where("owner", $club->getId() * -1)->where("special_type", 0)->where("deleted", false); + foreach ($albums->page($page, $perPage) as $album) { yield new Album($album); + } } - - function getClubAlbumsCount(Club $club): int + + public function getClubAlbumsCount(Club $club): int { - $albums = $this->albums->where("owner", $club->getId() * -1)->where("special_type", 0)->where("deleted", false); + $albums = $this->albums->where("owner", $club->getId() * -1)->where("special_type", 0)->where("deleted", false); return sizeof($albums); } - - function getAvatarAlbumById(int $id, int $regTime): Album + + public function getAvatarAlbumById(int $id, int $regTime): Album { $data = $this->getSpecialConditions($id, 16); $album = $this->albums->where([ "owner" => $id, "special_type" => 16, ])->fetch(); - if(!$album) { - $album = new Album; + if (!$album) { + $album = new Album(); $album->setName("[!!! internal album]"); $album->setOwner($id); $album->setSpecial_Type(16); $album->setCreated($regTime); $album->save(); - + return $album; } - + return new Album($album); } - - function getUserAvatarAlbum(User $user): Album + + public function getUserAvatarAlbum(User $user): Album { return $this->getAvatarAlbumById($user->getId(), $user->getRegistrationTime()->timestamp()); } - - function getClubAvatarAlbum(Club $club): Album + + public function getClubAvatarAlbum(Club $club): Album { return $this->getAvatarAlbumById($club->getId() * -1, time()); } - - function getUserWallAlbum(User $user): Album + + public function getUserWallAlbum(User $user): Album { $data = $this->getSpecialConditions($user->getId(), 32); $album = $this->albums->where([ "owner" => $user->getId(), "special_type" => 32, ])->fetch(); - if(!$album) { - $album = new Album; + if (!$album) { + $album = new Album(); $album->setName("[!!! internal album]"); $album->setOwner($user->getId()); $album->setSpecial_Type(32); $album->setCreated($user->getRegistrationTime()->timestamp()); $album->save(); - + return $album; } - + return new Album($album); } - function getAlbumByPhotoId(Photo $photo): ?Album + public function getAlbumByPhotoId(Photo $photo): ?Album { $dbalbum = $this->context->table("album_relations")->where(["media" => $photo->getId()])->fetch(); return $dbalbum->collection ? $this->get($dbalbum->collection) : null; } - function getAlbumByOwnerAndId(int $owner, int $id) + public function getAlbumByOwnerAndId(int $owner, int $id) { $album = $this->albums->where([ "owner" => $owner, - "id" => $id + "id" => $id, ])->fetch(); - return $album ? new Album($album) : NULL; + return $album ? new Album($album) : null; } } diff --git a/Web/Models/Repositories/Aliases.php b/Web/Models/Repositories/Aliases.php index e74532a1..d84d6768 100644 --- a/Web/Models/Repositories/Aliases.php +++ b/Web/Models/Repositories/Aliases.php @@ -1,4 +1,7 @@ -context = DB::i()->getContext(); $this->aliases = $this->context->table("aliases"); @@ -20,15 +23,15 @@ class Aliases private function toAlias(?ActiveRow $ar): ?Alias { - return is_null($ar) ? NULL : new Alias($ar); + return is_null($ar) ? null : new Alias($ar); } - function get(int $id): ?Alias + public function get(int $id): ?Alias { return $this->toAlias($this->aliases->get($id)); } - function getByShortcode(string $shortcode): ?Alias + public function getByShortcode(string $shortcode): ?Alias { return $this->toAlias($this->aliases->where("shortcode", $shortcode)->fetch()); } diff --git a/Web/Models/Repositories/Applications.php b/Web/Models/Repositories/Applications.php index c0906067..15c8a07c 100644 --- a/Web/Models/Repositories/Applications.php +++ b/Web/Models/Repositories/Applications.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->apps = $this->context->table("apps"); $this->appRels = $this->context->table("app_users"); } - + private function toApp(?ActiveRow $ar): ?Application { - return is_null($ar) ? NULL : new Application($ar); + return is_null($ar) ? null : new Application($ar); } - - function get(int $id): ?Application + + public function get(int $id): ?Application { return $this->toApp($this->apps->get($id)); } - - function getList(int $page = 1, ?int $perPage = NULL): \Traversable + + public function getList(int $page = 1, ?int $perPage = null): \Traversable { - $perPage = $perPage ?? OPENVK_DEFAULT_PER_PAGE; + $perPage ??= OPENVK_DEFAULT_PER_PAGE; $apps = $this->apps->where("enabled", 1)->page($page, $perPage); - foreach($apps as $app) + foreach ($apps as $app) { yield new Application($app); + } } - - function getListCount(): int + + public function getListCount(): int { return sizeof($this->apps->where("enabled", 1)); } - - function getByOwner(User $owner, int $page = 1, ?int $perPage = NULL): \Traversable + + public function getByOwner(User $owner, int $page = 1, ?int $perPage = null): \Traversable { - $perPage = $perPage ?? OPENVK_DEFAULT_PER_PAGE; + $perPage ??= OPENVK_DEFAULT_PER_PAGE; $apps = $this->apps->where("owner", $owner->getId())->page($page, $perPage); - foreach($apps as $app) + foreach ($apps as $app) { yield new Application($app); + } } - - function getOwnCount(User $owner): int + + public function getOwnCount(User $owner): int { return sizeof($this->apps->where("owner", $owner->getId())); } - - function getInstalled(User $user, int $page = 1, ?int $perPage = NULL): \Traversable + + public function getInstalled(User $user, int $page = 1, ?int $perPage = null): \Traversable { - $perPage = $perPage ?? OPENVK_DEFAULT_PER_PAGE; + $perPage ??= OPENVK_DEFAULT_PER_PAGE; $apps = $this->appRels->where("user", $user->getId())->page($page, $perPage); - foreach($apps as $appRel) + foreach ($apps as $appRel) { yield $this->get($appRel->app); + } } - - function getInstalledCount(User $user): int + + public function getInstalledCount(User $user): int { return sizeof($this->appRels->where("user", $user->getId())); } - function find(string $query = "", array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream + public function find(string $query = "", array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream { $query = "%$query%"; $result = $this->apps->where("CONCAT_WS(' ', name, description) LIKE ?", $query)->where("enabled", 1); $order_str = 'id'; - switch($order['type']) { + switch ($order['type']) { case 'id': $order_str = 'id ' . ($order['invert'] ? 'ASC' : 'DESC'); break; } - if($order_str) + if ($order_str) { $result->order($order_str); - + } + return new Util\EntityStream("Application", $result); } -} \ No newline at end of file +} diff --git a/Web/Models/Repositories/Audios.php b/Web/Models/Repositories/Audios.php index 1b8b174d..5be250ff 100644 --- a/Web/Models/Repositories/Audios.php +++ b/Web/Models/Repositories/Audios.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->audios = $this->context->table("audios"); @@ -34,53 +38,59 @@ class Audios $this->playlistRels = $this->context->table("playlist_relations"); } - function get(int $id): ?Audio + public function get(int $id): ?Audio { $audio = $this->audios->get($id); - if(!$audio) - return NULL; + if (!$audio) { + return null; + } return new Audio($audio); } - function getPlaylist(int $id): ?Playlist + public function getPlaylist(int $id): ?Playlist { $playlist = $this->playlists->get($id); - if(!$playlist) - return NULL; + if (!$playlist) { + return null; + } return new Playlist($playlist); } - function getByOwnerAndVID(int $owner, int $vId): ?Audio + public function getByOwnerAndVID(int $owner, int $vId): ?Audio { $audio = $this->audios->where([ "owner" => $owner, "virtual_id" => $vId, ])->fetch(); - if(!$audio) return NULL; + if (!$audio) { + return null; + } return new Audio($audio); } - function getPlaylistByOwnerAndVID(int $owner, int $vId): ?Playlist + public function getPlaylistByOwnerAndVID(int $owner, int $vId): ?Playlist { $playlist = $this->playlists->where([ "owner" => $owner, "id" => $vId, ])->fetch(); - if(!$playlist) return NULL; + if (!$playlist) { + return null; + } return new Playlist($playlist); } - function getByEntityID(int $entity, int $offset = 0, ?int $limit = NULL, ?int& $deleted = nullptr): \Traversable + public function getByEntityID(int $entity, int $offset = 0, ?int $limit = null, ?int& $deleted = nullptr): \Traversable { $limit ??= OPENVK_DEFAULT_PER_PAGE; $iter = $this->rels->where("entity", $entity)->limit($limit, $offset)->order("index DESC"); - foreach($iter as $rel) { + foreach ($iter as $rel) { $audio = $this->get($rel->audio); - if(!$audio || $audio->isDeleted()) { + if (!$audio || $audio->isDeleted()) { $deleted++; continue; } @@ -89,13 +99,13 @@ class Audios } } - function getPlaylistsByEntityId(int $entity, int $offset = 0, ?int $limit = NULL, ?int& $deleted = nullptr): \Traversable + public function getPlaylistsByEntityId(int $entity, int $offset = 0, ?int $limit = null, ?int& $deleted = nullptr): \Traversable { $limit ??= OPENVK_DEFAULT_PER_PAGE; $iter = $this->playlistImports->where("entity", $entity)->limit($limit, $offset); - foreach($iter as $rel) { + foreach ($iter as $rel) { $playlist = $this->getPlaylist($rel->playlist); - if(!$playlist || $playlist->isDeleted()) { + if (!$playlist || $playlist->isDeleted()) { $deleted++; continue; } @@ -104,18 +114,19 @@ class Audios } } - function getByUser(User $user, int $page = 1, ?int $perPage = NULL, ?int& $deleted = nullptr): \Traversable + public function getByUser(User $user, int $page = 1, ?int $perPage = null, ?int& $deleted = nullptr): \Traversable { return $this->getByEntityID($user->getId(), ($perPage * ($page - 1)), $perPage, $deleted); } - function getRandomThreeAudiosByEntityId(int $id): Array + public function getRandomThreeAudiosByEntityId(int $id): array { $iter = $this->rels->where("entity", $id); $ids = []; - foreach($iter as $it) + foreach ($iter as $it) { $ids[] = $it->audio; + } $shuffleSeed = openssl_random_pseudo_bytes(6); $shuffleSeed = hexdec(bin2hex($shuffleSeed)); @@ -124,11 +135,12 @@ class Audios $ids = array_slice($ids, 0, 3); $audios = []; - foreach($ids as $id) { - $audio = $this->get((int)$id); + foreach ($ids as $id) { + $audio = $this->get((int) $id); - if(!$audio || $audio->isDeleted()) + if (!$audio || $audio->isDeleted()) { continue; + } $audios[] = $audio; } @@ -136,47 +148,47 @@ class Audios return $audios; } - function getByClub(Club $club, int $page = 1, ?int $perPage = NULL, ?int& $deleted = nullptr): \Traversable + public function getByClub(Club $club, int $page = 1, ?int $perPage = null, ?int& $deleted = nullptr): \Traversable { return $this->getByEntityID($club->getId() * -1, ($perPage * ($page - 1)), $perPage, $deleted); } - function getPlaylistsByUser(User $user, int $page = 1, ?int $perPage = NULL, ?int& $deleted = nullptr): \Traversable + public function getPlaylistsByUser(User $user, int $page = 1, ?int $perPage = null, ?int& $deleted = nullptr): \Traversable { return $this->getPlaylistsByEntityId($user->getId(), ($perPage * ($page - 1)), $perPage, $deleted); } - function getPlaylistsByClub(Club $club, int $page = 1, ?int $perPage = NULL, ?int& $deleted = nullptr): \Traversable + public function getPlaylistsByClub(Club $club, int $page = 1, ?int $perPage = null, ?int& $deleted = nullptr): \Traversable { return $this->getPlaylistsByEntityId($club->getId() * -1, ($perPage * ($page - 1)), $perPage, $deleted); } - - function getCollectionSizeByEntityId(int $id): int + + public function getCollectionSizeByEntityId(int $id): int { return sizeof($this->rels->where("entity", $id)); } - function getUserCollectionSize(User $user): int + public function getUserCollectionSize(User $user): int { return sizeof($this->rels->where("entity", $user->getId())); } - function getClubCollectionSize(Club $club): int + public function getClubCollectionSize(Club $club): int { return sizeof($this->rels->where("entity", $club->getId() * -1)); } - function getUserPlaylistsCount(User $user): int + public function getUserPlaylistsCount(User $user): int { return sizeof($this->playlistImports->where("entity", $user->getId())); } - function getClubPlaylistsCount(Club $club): int + public function getClubPlaylistsCount(Club $club): int { return sizeof($this->playlistImports->where("entity", $club->getId() * -1)); } - function getByUploader(User $user): EntityStream + public function getByUploader(User $user): EntityStream { $search = $this->audios->where([ "owner" => $user->getId(), @@ -186,7 +198,7 @@ class Audios return new EntityStream("Audio", $search); } - function getGlobal(int $order, ?string $genreId = NULL): EntityStream + public function getGlobal(int $order, ?string $genreId = null): EntityStream { $search = $this->audios->where([ "deleted" => 0, @@ -194,13 +206,14 @@ class Audios "withdrawn" => 0, ])->order($order == Audios::ORDER_NEW ? "created DESC" : "listens DESC"); - if(!is_null($genreId)) + if (!is_null($genreId)) { $search = $search->where("genre", $genreId); + } return new EntityStream("Audio", $search); } - function search(string $query, int $sortMode = 0, bool $performerOnly = false, bool $withLyrics = false): EntityStream + public function search(string $query, int $sortMode = 0, bool $performerOnly = false, bool $withLyrics = false): EntityStream { $columns = $performerOnly ? "performer" : "performer, name"; $order = (["created", "length", "listens"][$sortMode] ?? "") . " DESC"; @@ -210,13 +223,14 @@ class Audios "deleted" => 0, ])->where("MATCH ($columns) AGAINST (? IN BOOLEAN MODE)", "%$query%")->order($order); - if($withLyrics) + if ($withLyrics) { $search = $search->where("lyrics IS NOT NULL"); + } return new EntityStream("Audio", $search); } - function searchPlaylists(string $query): EntityStream + public function searchPlaylists(string $query): EntityStream { $search = $this->playlists->where([ "unlisted" => 0, @@ -226,25 +240,25 @@ class Audios return new EntityStream("Playlist", $search); } - function getNew(): EntityStream + public function getNew(): EntityStream { return new EntityStream("Audio", $this->audios->where("created >= " . (time() - 259200))->where(["withdrawn" => 0, "deleted" => 0, "unlisted" => 0])->order("created DESC")->limit(25)); } - function getPopular(): EntityStream + public function getPopular(): EntityStream { return new EntityStream("Audio", $this->audios->where("listens > 0")->where(["withdrawn" => 0, "deleted" => 0, "unlisted" => 0])->order("listens DESC")->limit(25)); } - function isAdded(int $user_id, int $audio_id): bool + public function isAdded(int $user_id, int $audio_id): bool { return !is_null($this->rels->where([ "entity" => $user_id, - "audio" => $audio_id + "audio" => $audio_id, ])->fetch()); } - function find(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false], int $page = 1, ?int $perPage = NULL): \Traversable + public function find(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false], int $page = 1, ?int $perPage = null): \Traversable { $query = "%$query%"; $result = $this->audios->where([ @@ -253,18 +267,21 @@ class Audios /*"withdrawn" => 0, "processed" => 1,*/ ]); - $order_str = (in_array($order['type'], ['id', 'length', 'listens']) ? $order['type'] : 'id') . ' ' . ($order['invert'] ? 'ASC' : 'DESC');; + $order_str = (in_array($order['type'], ['id', 'length', 'listens']) ? $order['type'] : 'id') . ' ' . ($order['invert'] ? 'ASC' : 'DESC'); + ; - if($params["only_performers"] == "1") { + if ($params["only_performers"] == "1") { $result->where("performer LIKE ?", $query); } else { $result->where("CONCAT_WS(' ', performer, name) LIKE ?", $query); } - foreach($params as $paramName => $paramValue) { - if(is_null($paramValue) || $paramValue == '') continue; + foreach ($params as $paramName => $paramValue) { + if (is_null($paramValue) || $paramValue == '') { + continue; + } - switch($paramName) { + switch ($paramName) { case "before": $result->where("created < ?", $paramValue); break; @@ -275,20 +292,23 @@ class Audios $result->where("lyrics IS NOT NULL"); break; case 'genre': - if($paramValue == 'any') break; + if ($paramValue == 'any') { + break; + } $result->where("genre", $paramValue); break; } } - if($order_str) + if ($order_str) { $result->order($order_str); - + } + return new Util\EntityStream("Audio", $result); } - function findPlaylists(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false]): \Traversable + public function findPlaylists(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false]): \Traversable { $query = "%$query%"; $result = $this->playlists->where([ @@ -296,13 +316,16 @@ class Audios ])->where("CONCAT_WS(' ', name, description) LIKE ?", $query); $order_str = (in_array($order['type'], ['id', 'length', 'listens']) ? $order['type'] : 'id') . ' ' . ($order['invert'] ? 'ASC' : 'DESC'); - if(is_null($params['from_me']) || empty($params['from_me'])) + if (is_null($params['from_me']) || empty($params['from_me'])) { $result->where(["unlisted" => 0]); + } - foreach($params as $paramName => $paramValue) { - if(is_null($paramValue) || $paramValue == '') continue; + foreach ($params as $paramName => $paramValue) { + if (is_null($paramValue) || $paramValue == '') { + continue; + } - switch($paramName) { + switch ($paramName) { # БУДЬ МАКСИМАЛЬНО АККУРАТЕН С ДАННЫМ ПАРАМЕТРОМ case "from_me": $result->where("owner", $paramValue); @@ -310,8 +333,9 @@ class Audios } } - if($order_str) + if ($order_str) { $result->order($order_str); + } return new Util\EntityStream("Playlist", $result); } diff --git a/Web/Models/Repositories/BannedLinks.php b/Web/Models/Repositories/BannedLinks.php index 8f93e6fd..e048c526 100644 --- a/Web/Models/Repositories/BannedLinks.php +++ b/Web/Models/Repositories/BannedLinks.php @@ -1,5 +1,9 @@ -context = DB::i()->getContext(); $this->bannedLinks = $this->context->table("links_banned"); } - function toBannedLink(?ActiveRow $ar): ?BannedLink + public function toBannedLink(?ActiveRow $ar): ?BannedLink { - return is_null($ar) ? NULL : new BannedLink($ar); + return is_null($ar) ? null : new BannedLink($ar); } - function get(int $id): ?BannedLink + public function get(int $id): ?BannedLink { return $this->toBannedLink($this->bannedLinks->get($id)); } - function getList(?int $page = 1): \Traversable + public function getList(?int $page = 1): \Traversable { - foreach($this->bannedLinks->order("id DESC")->page($page, OPENVK_DEFAULT_PER_PAGE) as $link) + foreach ($this->bannedLinks->order("id DESC")->page($page, OPENVK_DEFAULT_PER_PAGE) as $link) { yield new BannedLink($link); + } } - function getCount(int $page = 1): int + public function getCount(int $page = 1): int { return sizeof($this->bannedLinks->fetch()); } - function getByDomain(string $domain): ?Selection + public function getByDomain(string $domain): ?Selection { return $this->bannedLinks->where("domain", $domain); } - function isDomainBanned(string $domain): bool + public function isDomainBanned(string $domain): bool { return sizeof($this->bannedLinks->where(["link" => $domain, "regexp_rule" => ""])) > 0; } - function genLinks($rules): \Traversable + public function genLinks($rules): \Traversable { - foreach ($rules as $rule) + foreach ($rules as $rule) { yield $this->get($rule->id); + } } - function genEntries($links, $uri): \Traversable + public function genEntries($links, $uri): \Traversable { - foreach($links as $link) - if (preg_match($link->getRegexpRule(), $uri)) + foreach ($links as $link) { + if (preg_match($link->getRegexpRule(), $uri)) { yield $link->getId(); + } + } } - function check(string $url): ?array + public function check(string $url): ?array { $uri = strstr(str_replace(["https://", "http://"], "", $url), "/", true); $domain = str_replace("www.", "", $uri); $rules = $this->getByDomain($domain); - if (is_null($rules)) - return NULL; + if (is_null($rules)) { + return null; + } return iterator_to_array($this->genEntries($this->genLinks($rules), $uri)); } -} \ No newline at end of file +} diff --git a/Web/Models/Repositories/Bans.php b/Web/Models/Repositories/Bans.php index 7123459d..16ff848b 100644 --- a/Web/Models/Repositories/Bans.php +++ b/Web/Models/Repositories/Bans.php @@ -1,5 +1,9 @@ -context = DB::i()->getContext(); $this->bans = $this->context->table("bans"); } - function toBan(?ActiveRow $ar): ?Ban + public function toBan(?ActiveRow $ar): ?Ban { - return is_null($ar) ? NULL : new Ban($ar); + return is_null($ar) ? null : new Ban($ar); } - function get(int $id): ?Ban + public function get(int $id): ?Ban { return $this->toBan($this->bans->get($id)); } - function getByUser(int $user_id): \Traversable + public function getByUser(int $user_id): \Traversable { - foreach ($this->bans->where("user", $user_id) as $ban) + foreach ($this->bans->where("user", $user_id) as $ban) { yield new Ban($ban); + } } -} \ No newline at end of file +} diff --git a/Web/Models/Repositories/ChandlerGroups.php b/Web/Models/Repositories/ChandlerGroups.php index 30b706e2..3c7c62de 100644 --- a/Web/Models/Repositories/ChandlerGroups.php +++ b/Web/Models/Repositories/ChandlerGroups.php @@ -1,5 +1,9 @@ -perms = $this->context->table("ChandlerACLGroupsPermissions"); } - function get(string $UUID): ?ActiveRow + public function get(string $UUID): ?ActiveRow { return $this->groups->where("id", $UUID)->fetch(); } - function getList(): \Traversable + public function getList(): \Traversable { - foreach($this->groups as $group) yield $group; + foreach ($this->groups as $group) { + yield $group; + } } - function getMembersById(string $UUID): \Traversable + public function getMembersById(string $UUID): \Traversable { - foreach($this->members->where("group", $UUID) as $member) - yield (new Users)->getByChandlerUser( + foreach ($this->members->where("group", $UUID) as $member) { + yield (new Users())->getByChandlerUser( new ChandlerUser($this->context->table("ChandlerUsers")->where("id", $member->user)->fetch()) ); + } } - function getUsersMemberships(string $UUID): \Traversable + public function getUsersMemberships(string $UUID): \Traversable { - foreach($this->members->where("user", $UUID) as $member) yield $member; + foreach ($this->members->where("user", $UUID) as $member) { + yield $member; + } } - function getPermissionsById(string $UUID): \Traversable + public function getPermissionsById(string $UUID): \Traversable { - foreach($this->perms->where("group", $UUID) as $perm) yield $perm; + foreach ($this->perms->where("group", $UUID) as $perm) { + yield $perm; + } } - function isUserAMember(string $GID, string $UID): bool + public function isUserAMember(string $GID, string $UID): bool { - return ($this->context->query("SELECT * FROM `ChandlerACLRelations` WHERE `group` = ? AND `user` = ?", $GID, $UID)) !== NULL; + return ($this->context->query("SELECT * FROM `ChandlerACLRelations` WHERE `group` = ? AND `user` = ?", $GID, $UID)) !== null; } } diff --git a/Web/Models/Repositories/ChandlerUsers.php b/Web/Models/Repositories/ChandlerUsers.php index 510e5860..1ba85548 100644 --- a/Web/Models/Repositories/ChandlerUsers.php +++ b/Web/Models/Repositories/ChandlerUsers.php @@ -1,5 +1,9 @@ -getChandlerUser(); + return is_null($ar) ? null : (new User($ar))->getChandlerUser(); } - function get(int $id): ?ChandlerUser + public function get(int $id): ?ChandlerUser { - return (new Users)->get($id)->getChandlerUser(); + return (new Users())->get($id)->getChandlerUser(); } - function getById(string $UUID): ?ChandlerUser + public function getById(string $UUID): ?ChandlerUser { $user = $this->users->where("id", $UUID)->fetch(); - return $user ? new ChandlerUser($user) : NULL; + return $user ? new ChandlerUser($user) : null; } - function getList(int $page = 1): \Traversable + public function getList(int $page = 1): \Traversable { - foreach($this->users as $user) + foreach ($this->users as $user) { yield new ChandlerUser($user); + } } } diff --git a/Web/Models/Repositories/Clubs.php b/Web/Models/Repositories/Clubs.php index de5d9269..b425c858 100644 --- a/Web/Models/Repositories/Clubs.php +++ b/Web/Models/Repositories/Clubs.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->clubs = $this->context->table("groups"); $this->coadmins = $this->context->table("group_coadmins"); } - + private function toClub(?ActiveRow $ar): ?Club { - return is_null($ar) ? NULL : new Club($ar); + return is_null($ar) ? null : new Club($ar); } - - function getByShortURL(string $url): ?Club + + public function getByShortURL(string $url): ?Club { $shortcode = $this->toClub($this->clubs->where("shortcode", $url)->fetch()); - if ($shortcode) + if ($shortcode) { return $shortcode; + } - $alias = (new Aliases)->getByShortcode($url); + $alias = (new Aliases())->getByShortcode($url); - if (!$alias) return NULL; - if ($alias->getType() !== "club") return NULL; + if (!$alias) { + return null; + } + if ($alias->getType() !== "club") { + return null; + } return $alias->getClub(); } - - function get(int $id): ?Club + + public function get(int $id): ?Club { return $this->toClub($this->clubs->get($id)); } - function getByIds(array $ids = []): array + public function getByIds(array $ids = []): array { $clubs = $this->clubs->select('*')->where('id IN (?)', $ids); $clubs_array = []; - foreach($clubs as $club) { + foreach ($clubs as $club) { $clubs_array[] = $this->toClub($club); } return $clubs_array; } - function find(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false], int $page = 1, ?int $perPage = NULL): \Traversable + public function find(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false], int $page = 1, ?int $perPage = null): \Traversable { $query = "%$query%"; $result = $this->clubs; $order_str = 'id'; - switch($order['type']) { + switch ($order['type']) { case 'id': $order_str = 'id ' . ($order['invert'] ? 'ASC' : 'DESC'); break; @@ -69,21 +79,22 @@ class Clubs $result = $result->where("name LIKE ? OR about LIKE ?", $query, $query); - if($order_str) + if ($order_str) { $result->order($order_str); + } return new Util\EntityStream("Club", $result); } - function getCount(): int + public function getCount(): int { return (clone $this->clubs)->count('*'); } - function getPopularClubs(): \Traversable + public function getPopularClubs(): \Traversable { // TODO rewrite - + /* $query = "SELECT ROW_NUMBER() OVER (ORDER BY `subscriptions` DESC) as `place`, `target` as `id`, COUNT(`follower`) as `subscriptions` FROM `subscriptions` WHERE `model` = \"openvk\\\Web\\\Models\\\Entities\\\Club\" GROUP BY `target` ORDER BY `subscriptions` DESC, `id` LIMIT 30;"; $entries = DatabaseConnection::i()->getConnection()->query($query); @@ -96,26 +107,24 @@ class Clubs ]; */ } - - function getWriteableClubs(int $id): \Traversable + + public function getWriteableClubs(int $id): \Traversable { $result = $this->clubs->where("owner", $id); $coadmins = $this->coadmins->where("user", $id); - - foreach($result as $entry) { + + foreach ($result as $entry) { yield new Club($entry); } - foreach($coadmins as $coadmin) { + foreach ($coadmins as $coadmin) { $cl = new Manager($coadmin); yield $cl->getClub(); } } - function getWriteableClubsCount(int $id): int + public function getWriteableClubsCount(int $id): int { return sizeof($this->clubs->where("owner", $id)) + sizeof($this->coadmins->where("user", $id)); } - - use \Nette\SmartObject; } diff --git a/Web/Models/Repositories/Comments.php b/Web/Models/Repositories/Comments.php index 811d1358..00b2bb85 100644 --- a/Web/Models/Repositories/Comments.php +++ b/Web/Models/Repositories/Comments.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->comments = $this->context->table("comments"); } - + private function toComment(?ActiveRow $ar): ?Comment { - return is_null($ar) ? NULL : new Comment($ar); + return is_null($ar) ? null : new Comment($ar); } - - function get(int $id): ?Comment + + public function get(int $id): ?Comment { return $this->toComment($this->comments->get($id)); } - - function getCommentsByTarget(Postable $target, int $page, ?int $perPage = NULL, ?string $sort = "ASC"): \Traversable + + public function getCommentsByTarget(Postable $target, int $page, ?int $perPage = null, ?string $sort = "ASC"): \Traversable { $comments = $this->comments->where([ "model" => get_class($target), "target" => $target->getId(), "deleted" => false, - ])->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE)->order("created ".$sort);; - - foreach($comments as $comment) + ])->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE)->order("created " . $sort); + ; + + foreach ($comments as $comment) { yield $this->toComment($comment); + } } - function getLastCommentsByTarget(Postable $target, ?int $count = NULL): \Traversable + public function getLastCommentsByTarget(Postable $target, ?int $count = null): \Traversable { $comments = $this->comments->where([ "model" => get_class($target), "target" => $target->getId(), "deleted" => false, ])->page(1, $count ?? OPENVK_DEFAULT_PER_PAGE)->order("created DESC"); - + $comments = array_reverse(iterator_to_array($comments)); - foreach($comments as $comment) + foreach ($comments as $comment) { yield $this->toComment($comment); + } } - - function getCommentsCountByTarget(Postable $target): int + + public function getCommentsCountByTarget(Postable $target): int { return sizeof($this->comments->where([ "model" => get_class($target), @@ -60,19 +67,19 @@ class Comments ])); } - function find(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream + public function find(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream { $result = $this->comments->where("content LIKE ?", "%$query%")->where("deleted", 0); $order_str = 'id'; - switch($order['type']) { + switch ($order['type']) { case 'id': $order_str = 'created ' . ($order['invert'] ? 'ASC' : 'DESC'); break; } - foreach($params as $paramName => $paramValue) { - switch($paramName) { + foreach ($params as $paramName => $paramValue) { + switch ($paramName) { case "before": $result->where("created < ?", $paramValue); break; @@ -82,8 +89,9 @@ class Comments } } - if($order_str) + if ($order_str) { $result->order($order_str); + } return new Util\EntityStream("Comment", $result); } diff --git a/Web/Models/Repositories/ContentSearchRepository.php b/Web/Models/Repositories/ContentSearchRepository.php index 65f03d93..b7cd7ea1 100644 --- a/Web/Models/Repositories/ContentSearchRepository.php +++ b/Web/Models/Repositories/ContentSearchRepository.php @@ -1,5 +1,9 @@ -ctx = DatabaseConnection::i()->getContext(); $this->builder = $this->ctx; } - + private function markParameterAsPassed(string $param): void { - if(!in_array($param, $this->passedParams)) + if (!in_array($param, $this->passedParams)) { $this->passedParams[] = $param; + } } - - function setContentType() - { - - } + + public function setContentType() {} } diff --git a/Web/Models/Repositories/Conversations.php b/Web/Models/Repositories/Conversations.php index 19179521..e354411b 100644 --- a/Web/Models/Repositories/Conversations.php +++ b/Web/Models/Repositories/Conversations.php @@ -1,5 +1,9 @@ -context = DB::i()->getContext(); $this->convos = $this->context->table("conversations"); } - + private function toConversation(?ActiveRow $ar): ?M\AbstractConversation { - if(is_null($ar)) - return NULL; - else if($ar->is_pm) + if (is_null($ar)) { + return null; + } elseif ($ar->is_pm) { return new M\PrivateConversation($ar); - else + } else { return new M\Conversation($ar); + } } - - function get(int $id): ?M\AbstractConversation + + public function get(int $id): ?M\AbstractConversation { return $this->toConversation($this->convos->get($id)); } - - function getConversationsByUser(User $user, int $page = 1, ?int $perPage = NULL) : \Traversable + + public function getConversationsByUser(User $user, int $page = 1, ?int $perPage = null): \Traversable { $rels = $this->context->table("conversation_members")->where([ "deleted" => false, "user" => $user->getId(), ])->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE); - foreach($rels as $rel) + foreach ($rels as $rel) { yield $this->get($rel->conversation); + } } - - function getPrivateConversation(User $user, int $peer): M\PrivateConversation + + public function getPrivateConversation(User $user, int $peer): M\PrivateConversation { ; } diff --git a/Web/Models/Repositories/CurrentUser.php b/Web/Models/Repositories/CurrentUser.php index c6cb942b..cec41b81 100644 --- a/Web/Models/Repositories/CurrentUser.php +++ b/Web/Models/Repositories/CurrentUser.php @@ -1,5 +1,9 @@ -user = $user; + } - if ($ip) + if ($ip) { $this->ip = $ip; + } - if ($useragent) + if ($useragent) { $this->useragent = $useragent; + } } public static function get($user, $ip, $useragent) { - if (self::$instance === null) self::$instance = new self($user, $ip, $useragent); + if (self::$instance === null) { + self::$instance = new self($user, $ip, $useragent); + } return self::$instance; } diff --git a/Web/Models/Repositories/Documents.php b/Web/Models/Repositories/Documents.php index da388cc0..cda95abc 100644 --- a/Web/Models/Repositories/Documents.php +++ b/Web/Models/Repositories/Documents.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->documents = $this->context->table("documents"); } - + private function toDocument(?ActiveRow $ar): ?Document { - return is_null($ar) ? NULL : new Document($ar); + return is_null($ar) ? null : new Document($ar); } - - function get(int $id): ?Document + + public function get(int $id): ?Document { return $this->toDocument($this->documents->get($id)); } - + # By "Virtual ID" and "Absolute ID" (to not leak owner's id). - function getDocumentById(int $virtual_id, int $real_id, string $access_key = NULL): ?Document + public function getDocumentById(int $virtual_id, int $real_id, string $access_key = null): ?Document { $doc = $this->documents->where(['virtual_id' => $virtual_id, 'id' => $real_id]); /*if($access_key) { @@ -35,30 +39,33 @@ class Documents }*/ $doc = $doc->fetch(); - if(is_null($doc)) - return NULL; + if (is_null($doc)) { + return null; + } $n_doc = new Document($doc); - if(!$n_doc->checkAccessKey($access_key)) - return NULL; + if (!$n_doc->checkAccessKey($access_key)) { + return null; + } return $n_doc; } - function getDocumentByIdUnsafe(int $virtual_id, int $real_id): ?Document + public function getDocumentByIdUnsafe(int $virtual_id, int $real_id): ?Document { $doc = $this->documents->where(['virtual_id' => $virtual_id, 'id' => $real_id]); $doc = $doc->fetch(); - if(is_null($doc)) - return NULL; + if (is_null($doc)) { + return null; + } $n_doc = new Document($doc); return $n_doc; } - function getDocumentsByOwner(int $owner, int $order = 0, int $type = -1): EntityStream + public function getDocumentsByOwner(int $owner, int $order = 0, int $type = -1): EntityStream { $search = $this->documents->where([ "owner" => $owner, @@ -66,11 +73,11 @@ class Documents "deleted" => 0, ]); - if(in_array($type, [1,2,3,4,5,6,7,8])) { + if (in_array($type, [1,2,3,4,5,6,7,8])) { $search->where("type", $type); } - switch($order) { + switch ($order) { case 0: $search->order("id DESC"); break; @@ -85,14 +92,16 @@ class Documents return new EntityStream("Document", $search); } - function getTypes(int $owner_id): array + public function getTypes(int $owner_id): array { $result = DatabaseConnection::i()->getConnection()->query("SELECT `type`, COUNT(*) AS `count` FROM `documents` WHERE `owner` = ? AND `deleted` = 0 AND `unlisted` = 0 GROUP BY `type` ORDER BY `type`", $owner_id); $response = []; - foreach($result as $res) { - if($res->count < 1 || $res->type == 0) continue; + foreach ($result as $res) { + if ($res->count < 1 || $res->type == 0) { + continue; + } - $name = tr("document_type_".$res->type); + $name = tr("document_type_" . $res->type); $response[] = [ "count" => $res->count, "type" => $res->type, @@ -103,45 +112,48 @@ class Documents return $response; } - function getTags(int $owner_id, ?int $type = 0): array + public function getTags(int $owner_id, ?int $type = 0): array { $query = "SELECT `tags` FROM `documents` WHERE `owner` = ? AND `deleted` = 0 AND `unlisted` = 0 "; - if($type > 0 && $type < 9) { + if ($type > 0 && $type < 9) { $query .= "AND `type` = $type"; } $query .= " AND `tags` IS NOT NULL ORDER BY `id`"; $result = DatabaseConnection::i()->getConnection()->query($query, $owner_id); $tags = []; - foreach($result as $res) { + foreach ($result as $res) { $tags[] = $res->tags; } $imploded_tags = implode(",", $tags); $exploded_tags = array_values(array_unique(explode(",", $imploded_tags))); - if($exploded_tags[0] == "") + if ($exploded_tags[0] == "") { return []; - + } + return array_slice($exploded_tags, 0, 50); } - function find(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream + public function find(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream { $result = $this->documents->where("name LIKE ?", "%$query%")->where([ "deleted" => 0, - "folder_id != " => 0, + "folder_id != " => 0, ]); $order_str = 'id'; - switch($order['type']) { + switch ($order['type']) { case 'id': $order_str = 'created ' . ($order['invert'] ? 'ASC' : 'DESC'); break; } - foreach($params as $paramName => $paramValue) { - switch($paramName) { + foreach ($params as $paramName => $paramValue) { + switch ($paramName) { case "type": - if($paramValue < 1 || $paramValue > 8) continue; + if ($paramValue < 1 || $paramValue > 8) { + continue; + } $result->where("type", $paramValue); break; case "tags": @@ -153,8 +165,9 @@ class Documents } } - if($order_str) + if ($order_str) { $result->order($order_str); + } return new Util\EntityStream("Document", $result); } diff --git a/Web/Models/Repositories/EmailChangeVerifications.php b/Web/Models/Repositories/EmailChangeVerifications.php index 0e8c668b..64cdd83f 100644 --- a/Web/Models/Repositories/EmailChangeVerifications.php +++ b/Web/Models/Repositories/EmailChangeVerifications.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->verifications = $this->context->table("email_change_verifications"); } - function toEmailChangeVerification(?ActiveRow $ar): ?EmailChangeVerification + public function toEmailChangeVerification(?ActiveRow $ar): ?EmailChangeVerification { - return is_null($ar) ? NULL : new EmailChangeVerification($ar); + return is_null($ar) ? null : new EmailChangeVerification($ar); } - - function getByToken(string $token): ?EmailChangeVerification + + public function getByToken(string $token): ?EmailChangeVerification { return $this->toEmailChangeVerification($this->verifications->where("key", $token)->fetch()); } - - function getLatestByUser(User $user): ?EmailChangeVerification + + public function getLatestByUser(User $user): ?EmailChangeVerification { return $this->toEmailChangeVerification($this->verifications->where("profile", $user->getId())->order("timestamp DESC")->fetch()); } diff --git a/Web/Models/Repositories/Gifts.php b/Web/Models/Repositories/Gifts.php index 3baa2397..61831b18 100644 --- a/Web/Models/Repositories/Gifts.php +++ b/Web/Models/Repositories/Gifts.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->gifts = $this->context->table("gifts"); $this->cats = $this->context->table("gift_categories"); } - - function get(int $id): ?Gift + + public function get(int $id): ?Gift { $gift = $this->gifts->get($id); - if(!$gift) - return NULL; - + if (!$gift) { + return null; + } + return new Gift($gift); } - - function getCat(int $id): ?GiftCategory + + public function getCat(int $id): ?GiftCategory { $cat = $this->cats->get($id); - if(!$cat) - return NULL; - + if (!$cat) { + return null; + } + return new GiftCategory($cat); } - - function getCategories(int $page, ?int $perPage = NULL, &$count = nullptr): \Traversable + + public function getCategories(int $page, ?int $perPage = null, &$count = nullptr): \Traversable { $cats = $this->cats->where("deleted", false); $count = $cats->count(); $cats = $cats->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE); - foreach($cats as $cat) + foreach ($cats as $cat) { yield new GiftCategory($cat); + } } - function getCategoriesCount(): int + public function getCategoriesCount(): int { $cats = $this->cats->where("deleted", false); return $cats->count(); diff --git a/Web/Models/Repositories/IPs.php b/Web/Models/Repositories/IPs.php index 59fc6570..5991ccff 100644 --- a/Web/Models/Repositories/IPs.php +++ b/Web/Models/Repositories/IPs.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->ips = $this->context->table("ip"); } - - function get(string $ip): ?IP + + public function get(string $ip): ?IP { $bip = inet_pton($ip); - if(!$bip) + if (!$bip) { throw new \UnexpectedValueException("Malformed IP address"); - + } + $res = $this->ips->where("ip", $bip)->fetch(); - if(!$res) { - $res = new IP; + if (!$res) { + $res = new IP(); $res->setIp($ip); $res->save(false); - + return $res; } - + return new IP($res); } } diff --git a/Web/Models/Repositories/Managers.php b/Web/Models/Repositories/Managers.php index 9f65cb18..a3cf636f 100644 --- a/Web/Models/Repositories/Managers.php +++ b/Web/Models/Repositories/Managers.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); - $this->managers= $this->context->table("group_coadmins"); + $this->managers = $this->context->table("group_coadmins"); } - + private function toManager(?ActiveRow $ar): ?Manager { - return is_null($ar) ? NULL : new Manager($ar); + return is_null($ar) ? null : new Manager($ar); } - - function get(int $id): ?Manager + + public function get(int $id): ?Manager { return $this->toManager($this->managers->where("id", $id)->fetch()); } - function getByUserAndClub(int $user, int $club): ?Manager + public function getByUserAndClub(int $user, int $club): ?Manager { return $this->toManager($this->managers->where("user", $user)->where("club", $club)->fetch()); } - - use \Nette\SmartObject; } diff --git a/Web/Models/Repositories/Messages.php b/Web/Models/Repositories/Messages.php index 538338ed..e267a8da 100644 --- a/Web/Models/Repositories/Messages.php +++ b/Web/Models/Repositories/Messages.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->messages = $this->context->table("messages"); } - - function get(int $id): ?Message + + public function get(int $id): ?Message { $msg = $this->messages->get($id); - if(!$msg) - return NULL; - + if (!$msg) { + return null; + } + return new Message($msg); } - - function getCorrespondencies(RowModel $correspondent, int $page = 1, ?int $perPage = NULL, ?int $offset = NULL): \Traversable + + public function getCorrespondencies(RowModel $correspondent, int $page = 1, ?int $perPage = null, ?int $offset = null): \Traversable { $id = $correspondent->getId(); $class = get_class($correspondent); $limit = $perPage ?? OPENVK_DEFAULT_PER_PAGE; - $offset = $offset ?? ($page - 1) * $limit; + $offset ??= ($page - 1) * $limit; $query = file_get_contents(__DIR__ . "/../sql/get-correspondencies.tsql"); DatabaseConnection::i()->getConnection()->query(file_get_contents(__DIR__ . "/../sql/mysql-msg-fix.tsql")); $coresps = DatabaseConnection::i()->getConnection()->query($query, $id, $class, $id, $class, $limit, $offset); - foreach($coresps as $c) { - if($c->class === 'openvk\Web\Models\Entities\User') - $anotherCorrespondent = (new Users)->get($c->id); - else if($c->class === 'openvk\Web\Models\Entities\Club') - $anotherCorrespondent = (new Clubs)->get($c->id); - + foreach ($coresps as $c) { + if ($c->class === 'openvk\Web\Models\Entities\User') { + $anotherCorrespondent = (new Users())->get($c->id); + } elseif ($c->class === 'openvk\Web\Models\Entities\Club') { + $anotherCorrespondent = (new Clubs())->get($c->id); + } + yield new Correspondence($correspondent, $anotherCorrespondent); } } - - function getCorrespondenciesCount(RowModel $correspondent): ?int + + public function getCorrespondenciesCount(RowModel $correspondent): ?int { $id = $correspondent->getId(); $class = get_class($correspondent); diff --git a/Web/Models/Repositories/NoSpamLogs.php b/Web/Models/Repositories/NoSpamLogs.php index f8dd4980..420cbc85 100644 --- a/Web/Models/Repositories/NoSpamLogs.php +++ b/Web/Models/Repositories/NoSpamLogs.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->noSpamLogs = $this->context->table("noSpam_templates"); } - + private function toNoSpamLog(?ActiveRow $ar): ?NoSpamLog { - return is_null($ar) ? NULL : new NoSpamLog($ar); + return is_null($ar) ? null : new NoSpamLog($ar); } - - function get(int $id): ?NoSpamLog + + public function get(int $id): ?NoSpamLog { return $this->toNoSpamLog($this->noSpamLogs->get($id)); } - - function getList(array $filter = []): \Traversable + + public function getList(array $filter = []): \Traversable { - foreach ($this->noSpamLogs->where($filter)->order("`id` DESC") as $log) + foreach ($this->noSpamLogs->where($filter)->order("`id` DESC") as $log) { yield new NoSpamLog($log); + } } } diff --git a/Web/Models/Repositories/Notes.php b/Web/Models/Repositories/Notes.php index 0473070a..62bc3d33 100644 --- a/Web/Models/Repositories/Notes.php +++ b/Web/Models/Repositories/Notes.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->notes = $this->context->table("notes"); } - + private function toNote(?ActiveRow $ar): ?Note { - return is_null($ar) ? NULL : new Note($ar); + return is_null($ar) ? null : new Note($ar); } - - function get(int $id): ?Note + + public function get(int $id): ?Note { return $this->toNote($this->notes->get($id)); } - - function getUserNotes(User $user, int $page = 1, ?int $perPage = NULL, string $sort = "DESC"): \Traversable + + public function getUserNotes(User $user, int $page = 1, ?int $perPage = null, string $sort = "DESC"): \Traversable { - $perPage = $perPage ?? OPENVK_DEFAULT_PER_PAGE; - foreach($this->notes->where("owner", $user->getId())->where("deleted", 0)->order("created $sort")->page($page, $perPage) as $album) + $perPage ??= OPENVK_DEFAULT_PER_PAGE; + foreach ($this->notes->where("owner", $user->getId())->where("deleted", 0)->order("created $sort")->page($page, $perPage) as $album) { yield new Note($album); + } } - function getNoteById(int $owner, int $note): ?Note + public function getNoteById(int $owner, int $note): ?Note { $note = $this->notes->where(['owner' => $owner, 'virtual_id' => $note])->fetch(); - if(!is_null($note)) + if (!is_null($note)) { return new Note($note); - else - return NULL; + } else { + return null; + } } - - function getUserNotesCount(User $user): int + + public function getUserNotesCount(User $user): int { return sizeof($this->notes->where("owner", $user->getId())->where("deleted", 0)); } diff --git a/Web/Models/Repositories/Notifications.php b/Web/Models/Repositories/Notifications.php index ccbf7c27..81881f09 100644 --- a/Web/Models/Repositories/Notifications.php +++ b/Web/Models/Repositories/Notifications.php @@ -1,111 +1,113 @@ -modelCodes = array_flip(json_decode(file_get_contents(__DIR__ . "/../../../data/modelCodes.json"), true)); } - + private function getEDB(bool $throw = true): ?object { $eax = $this->edbc ?? eventdb(); - if(!$eax && $throw) + if (!$eax && $throw) { throw new \RuntimeException("Event database err!"); - - return is_null($eax) ? NULL : $eax->getConnection(); + } + + return is_null($eax) ? null : $eax->getConnection(); } - + private function getModel(int $code, int $id): object { $repoClassName = str_replace("Entities", "Repositories", "\\" . $this->modelCodes[$code]) . "s"; - - return (new $repoClassName)->get($id); + + return (new $repoClassName())->get($id); } - - private function getQuery(User $user, bool $count, int $offset, bool $archived = false, int $page = 1, ?int $perPage = NULL): string + + private function getQuery(User $user, bool $count, int $offset, bool $archived = false, int $page = 1, ?int $perPage = null): string { $query = "SELECT " . ($count ? "COUNT(*) AS cnt" : "*") . " FROM notifications WHERE recipientType=0 "; $query .= "AND timestamp " . ($archived ? "<" : ">") . "$offset AND recipientId=" . $user->getId(); - if(!$count) { + if (!$count) { $query .= " ORDER BY timestamp DESC"; $query .= " LIMIT " . ($perPage ?? OPENVK_DEFAULT_PER_PAGE); $query .= " OFFSET " . (($page - 1) * ($perPage ?? OPENVK_DEFAULT_PER_PAGE)); } - + return $query; } - - private function assemble(int $act, int $originModelType, int $originModelId, int $targetModelType, int $targetModelId, int $recipientId, int $timestamp, $data, ?string $class = NULL): Notification + + private function assemble(int $act, int $originModelType, int $originModelId, int $targetModelType, int $targetModelId, int $recipientId, int $timestamp, $data, ?string $class = null): Notification { $class ??= 'openvk\Web\Models\Entities\Notifications\Notification'; - + $originModel = $this->getModel($originModelType, $originModelId); $targetModel = $this->getModel($targetModelType, $targetModelId); - $recipient = (new Users)->get($recipientId); - + $recipient = (new Users())->get($recipientId); + $notification = new $class($recipient, $originModel, $targetModel, $timestamp, $data); $notification->setActionCode($act); return $notification; } - - function getNotificationCountByUser(User $user, int $offset, bool $archived = false): int + + public function getNotificationCountByUser(User $user, int $offset, bool $archived = false): int { $db = $this->getEDB(false); - if(!$db) + if (!$db) { return 0; - + } + $results = $db->query($this->getQuery($user, true, $offset, $archived)); - + return $results->fetch()->cnt; } - - function getNotificationsByUser(User $user, int $offset, bool $archived = false, int $page = 1, ?int $perPage = NULL): \Traversable + + public function getNotificationsByUser(User $user, int $offset, bool $archived = false, int $page = 1, ?int $perPage = null): \Traversable { $db = $this->getEDB(false); - if(!$db) { + if (!$db) { yield from []; return; } - + $results = $this->getEDB()->query($this->getQuery($user, false, $offset, $archived, $page, $perPage)); - foreach($results->fetchAll() as $notif) { + foreach ($results->fetchAll() as $notif) { yield $this->assemble( $notif->modelAction, $notif->originModelType, $notif->originModelId, - $notif->targetModelType, $notif->targetModelId, - $notif->recipientId, $notif->timestamp, $notif->additionalData ); } } - - function fromDescriptor(string $descriptor, ?object &$parsedData = nullptr) + + public function fromDescriptor(string $descriptor, ?object &$parsedData = nullptr) { [$class, $recv, $data] = explode(",", $descriptor); $class = str_replace(".", "\\", $class); - + $parsedData = unserialize(base64_decode($data)); return $this->assemble( $parsedData->actionCode, $parsedData->originModelType, $parsedData->originModelId, - $parsedData->targetModelType, $parsedData->targetModelId, - $parsedData->recipient, $parsedData->timestamp, $parsedData->additionalPayload, diff --git a/Web/Models/Repositories/Photos.php b/Web/Models/Repositories/Photos.php index 21d4a806..47c022b5 100644 --- a/Web/Models/Repositories/Photos.php +++ b/Web/Models/Repositories/Photos.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->photos = $this->context->table("photos"); } - - function get(int $id): ?Photo + + public function get(int $id): ?Photo { $photo = $this->photos->get($id); - if(!$photo) return NULL; - + if (!$photo) { + return null; + } + return new Photo($photo); } - - function getByOwnerAndVID(int $owner, int $vId): ?Photo + + public function getByOwnerAndVID(int $owner, int $vId): ?Photo { $photo = $this->photos->where([ "owner" => $owner, @@ -30,14 +36,16 @@ class Photos "system" => 0, "private" => 0, ])->fetch(); - if(!$photo) return NULL; - + if (!$photo) { + return null; + } + return new Photo($photo); } - function getEveryUserPhoto(User $user, int $offset = 0, int $limit = 10): \Traversable + public function getEveryUserPhoto(User $user, int $offset = 0, int $limit = 10): \Traversable { - $perPage = $perPage ?? OPENVK_DEFAULT_PER_PAGE; + $perPage ??= OPENVK_DEFAULT_PER_PAGE; $photos = $this->photos->where([ "owner" => $user->getId(), "deleted" => 0, @@ -45,12 +53,12 @@ class Photos "private" => 0, ])->order("id DESC"); - foreach($photos->limit($limit, $offset) as $photo) { + foreach ($photos->limit($limit, $offset) as $photo) { yield new Photo($photo); } } - function getUserPhotosCount(User $user) + public function getUserPhotosCount(User $user) { $photos = $this->photos->where([ "owner" => $user->getId(), diff --git a/Web/Models/Repositories/Polls.php b/Web/Models/Repositories/Polls.php index c2ba720b..555a0312 100644 --- a/Web/Models/Repositories/Polls.php +++ b/Web/Models/Repositories/Polls.php @@ -1,23 +1,28 @@ -polls = DatabaseConnection::i()->getContext()->table("polls"); } - - function get(int $id): ?Poll + + public function get(int $id): ?Poll { $poll = $this->polls->get($id); - if(!$poll) - return NULL; - + if (!$poll) { + return null; + } + return new Poll($poll); } -} \ No newline at end of file +} diff --git a/Web/Models/Repositories/Posts.php b/Web/Models/Repositories/Posts.php index f5fef282..bae4a839 100644 --- a/Web/Models/Repositories/Posts.php +++ b/Web/Models/Repositories/Posts.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->posts = $this->context->table("posts"); } - + private function toPost(?ActiveRow $ar): ?Post { - return is_null($ar) ? NULL : new Post($ar); + return is_null($ar) ? null : new Post($ar); } - - function get(int $id): ?Post + + public function get(int $id): ?Post { return $this->toPost($this->posts->get($id)); } - - function getPinnedPost(int $user): ?Post + + public function getPinnedPost(int $user): ?Post { $post = (clone $this->posts)->where([ "wall" => $user, "pinned" => true, "deleted" => false, ])->fetch(); - + return $this->toPost($post); } - - function getPostsFromUsersWall(int $user, int $page = 1, ?int $perPage = NULL, ?int $offset = NULL): \Traversable + + public function getPostsFromUsersWall(int $user, int $page = 1, ?int $perPage = null, ?int $offset = null): \Traversable { $perPage ??= OPENVK_DEFAULT_PER_PAGE; $offset ??= $perPage * ($page - 1); - + $pinPost = $this->getPinnedPost($user); - if(is_null($offset) || $offset == 0) { - if(!is_null($pinPost)) { - if($page === 1) { + if (is_null($offset) || $offset == 0) { + if (!is_null($pinPost)) { + if ($page === 1) { $perPage--; - + yield $pinPost; } else { $offset--; } } - } else if(!is_null($offset) && $pinPost) { + } elseif (!is_null($offset) && $pinPost) { $offset--; } - + $sel = $this->posts->where([ "wall" => $user, "pinned" => false, "deleted" => false, "suggested" => 0, ])->order("created DESC")->limit($perPage, $offset); - - foreach($sel as $post) + + foreach ($sel as $post) { yield new Post($post); + } } - function getOwnersPostsFromWall(int $user, int $page = 1, ?int $perPage = NULL, ?int $offset = NULL): \Traversable + public function getOwnersPostsFromWall(int $user, int $page = 1, ?int $perPage = null, ?int $offset = null): \Traversable { $perPage ??= OPENVK_DEFAULT_PER_PAGE; $offset ??= $perPage * ($page - 1); @@ -78,19 +83,21 @@ class Posts "deleted" => false, "suggested" => 0, ]); - - if($user > 0) + + if ($user > 0) { $sel->where("owner", $user); - else + } else { $sel->where("flags !=", 0); + } $sel->order("created DESC")->limit($perPage, $offset); - - foreach($sel as $post) + + foreach ($sel as $post) { yield new Post($post); + } } - function getOthersPostsFromWall(int $user, int $page = 1, ?int $perPage = NULL, ?int $offset = NULL): \Traversable + public function getOthersPostsFromWall(int $user, int $page = 1, ?int $perPage = null, ?int $offset = null): \Traversable { $perPage ??= OPENVK_DEFAULT_PER_PAGE; $offset ??= $perPage * ($page - 1); @@ -100,19 +107,21 @@ class Posts "deleted" => false, "suggested" => 0, ]); - - if($user > 0) + + if ($user > 0) { $sel->where("owner !=", $user); - else + } else { $sel->where("flags", 0); - + } + $sel->order("created DESC")->limit($perPage, $offset); - - foreach($sel as $post) + + foreach ($sel as $post) { yield new Post($post); + } } - - function getPostsByHashtag(string $hashtag, int $page = 1, ?int $perPage = NULL): \Traversable + + public function getPostsByHashtag(string $hashtag, int $page = 1, ?int $perPage = null): \Traversable { $hashtag = "#$hashtag"; $sel = $this->posts @@ -121,102 +130,109 @@ class Posts ->order("created DESC") ->where("suggested", 0) ->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE); - - foreach($sel as $post) + + foreach ($sel as $post) { yield new Post($post); + } } - - function getPostCountByHashtag(string $hashtag): int + + public function getPostCountByHashtag(string $hashtag): int { $hashtag = "#$hashtag"; $sel = $this->posts ->where("content LIKE ?", "%$hashtag%") ->where("deleted", 0) ->where("suggested", 0); - + return sizeof($sel); } - - function getPostById(int $wall, int $post, bool $forceSuggestion = false): ?Post + + public function getPostById(int $wall, int $post, bool $forceSuggestion = false): ?Post { $post = $this->posts->where(['wall' => $wall, 'virtual_id' => $post]); - if(!$forceSuggestion) { + if (!$forceSuggestion) { $post->where("suggested", 0); } $post = $post->fetch(); - if(!is_null($post)) + if (!is_null($post)) { return new Post($post); - else - return NULL; - + } else { + return null; + } + } - function find(string $query = "", array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream + public function find(string $query = "", array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream { $query = "%$query%"; $result = $this->posts->where("content LIKE ?", $query)->where("deleted", 0)->where("suggested", 0); $order_str = 'id'; - switch($order['type']) { + switch ($order['type']) { case 'id': $order_str = 'created ' . ($order['invert'] ? 'ASC' : 'DESC'); break; } - foreach($params as $paramName => $paramValue) { - if(is_null($paramValue) || $paramValue == '') continue; + foreach ($params as $paramName => $paramValue) { + if (is_null($paramValue) || $paramValue == '') { + continue; + } - switch($paramName) { + switch ($paramName) { case "before": $result->where("created < ?", $paramValue); break; case "after": $result->where("created > ?", $paramValue); break; - /*case 'die_in_agony': - $result->where("nsfw", 1); - break; - case 'ads': - $result->where("ad", 1); - break;*/ - # БУДЬ МАКСИМАЛЬНО АККУРАТЕН С ДАННЫМ ПАРАМЕТРОМ + /*case 'die_in_agony': + $result->where("nsfw", 1); + break; + case 'ads': + $result->where("ad", 1); + break;*/ + # БУДЬ МАКСИМАЛЬНО АККУРАТЕН С ДАННЫМ ПАРАМЕТРОМ case 'from_me': $result->where("owner", $paramValue); break; } } - if($order_str) + if ($order_str) { $result->order($order_str); + } return new Util\EntityStream("Post", $result); } - function getPostCountOnUserWall(int $user): int + public function getPostCountOnUserWall(int $user): int { return sizeof($this->posts->where(["wall" => $user, "deleted" => 0, "suggested" => 0])); } - function getOwnersCountOnUserWall(int $user): int + public function getOwnersCountOnUserWall(int $user): int { - if($user > 0) + if ($user > 0) { return sizeof($this->posts->where(["wall" => $user, "deleted" => 0, "owner" => $user])); - else + } else { return sizeof($this->posts->where(["wall" => $user, "deleted" => 0, "suggested" => 0])->where("flags !=", 0)); + } } - function getOthersCountOnUserWall(int $user): int + public function getOthersCountOnUserWall(int $user): int { - if($user > 0) + if ($user > 0) { return sizeof($this->posts->where(["wall" => $user, "deleted" => 0])->where("owner !=", $user)); - else + } else { return sizeof($this->posts->where(["wall" => $user, "deleted" => 0, "suggested" => 0])->where("flags", 0)); + } } - function getSuggestedPosts(int $club, int $page = 1, ?int $perPage = NULL, ?int $offset = NULL): \Traversable + public function getSuggestedPosts(int $club, int $page = 1, ?int $perPage = null, ?int $offset = null): \Traversable { $perPage ??= OPENVK_DEFAULT_PER_PAGE; $offset ??= $perPage * ($page - 1); @@ -227,17 +243,18 @@ class Posts ->order("created DESC") ->where("suggested", 1) ->limit($perPage, $offset); - - foreach($sel as $post) + + foreach ($sel as $post) { yield new Post($post); + } } - function getSuggestedPostsCount(int $club) + public function getSuggestedPostsCount(int $club) { return sizeof($this->posts->where(["wall" => $club * -1, "deleted" => 0, "suggested" => 1])); } - function getSuggestedPostsByUser(int $club, int $user, int $page = 1, ?int $perPage = NULL, ?int $offset = NULL): \Traversable + public function getSuggestedPostsByUser(int $club, int $user, int $page = 1, ?int $perPage = null, ?int $offset = null): \Traversable { $perPage ??= OPENVK_DEFAULT_PER_PAGE; $offset ??= $perPage * ($page - 1); @@ -249,17 +266,18 @@ class Posts ->order("created DESC") ->where("suggested", 1) ->limit($perPage, $offset); - - foreach($sel as $post) + + foreach ($sel as $post) { yield new Post($post); + } } - function getSuggestedPostsCountByUser(int $club, int $user): int - { + public function getSuggestedPostsCountByUser(int $club, int $user): int + { return sizeof($this->posts->where(["wall" => $club * -1, "deleted" => 0, "suggested" => 1, "owner" => $user])); } - function getCount(): int + public function getCount(): int { return (clone $this->posts)->count('*'); } diff --git a/Web/Models/Repositories/Reports.php b/Web/Models/Repositories/Reports.php index edce8980..b459f053 100644 --- a/Web/Models/Repositories/Reports.php +++ b/Web/Models/Repositories/Reports.php @@ -1,67 +1,80 @@ -context = DatabaseConnection::i()->getContext(); $this->reports = $this->context->table("reports"); } - + private function toReport(?ActiveRow $ar): ?Report { - return is_null($ar) ? NULL : new Report($ar); + return is_null($ar) ? null : new Report($ar); } - - function getReports(int $state = 0, int $page = 1, ?string $type = NULL, ?bool $pagination = true): \Traversable + + public function getReports(int $state = 0, int $page = 1, ?string $type = null, ?bool $pagination = true): \Traversable { $filter = ["deleted" => 0]; - if ($type) $filter["type"] = $type; + if ($type) { + $filter["type"] = $type; + } $reports = $this->reports->where($filter)->order("created DESC")->group("target_id, type"); - if ($pagination) + if ($pagination) { $reports = $reports->page($page, 15); + } - foreach($reports as $t) + foreach ($reports as $t) { yield new Report($t); + } } - - function getReportsCount(int $state = 0): int + + public function getReportsCount(int $state = 0): int { return sizeof($this->reports->where(["deleted" => 0, "type" => $state])->group("target_id, type")); } - - function get(int $id): ?Report + + public function get(int $id): ?Report { return $this->toReport($this->reports->get($id)); } - - function getByContentId(int $id): ?Report + + public function getByContentId(int $id): ?Report { $post = $this->reports->where(["deleted" => 0, "content_id" => $id])->fetch(); - if($post) + if ($post) { return new Report($post); - else - return null; + } else { + return null; + } } - function getDuplicates(string $type, int $target_id, ?int $orig = NULL, ?int $user_id = NULL): \Traversable + public function getDuplicates(string $type, int $target_id, ?int $orig = null, ?int $user_id = null): \Traversable { $filter = ["deleted" => 0, "type" => $type, "target_id" => $target_id]; - if ($orig) $filter[] = "id != $orig"; - if ($user_id) $filter["user_id"] = $user_id; + if ($orig) { + $filter[] = "id != $orig"; + } + if ($user_id) { + $filter["user_id"] = $user_id; + } - foreach ($this->reports->where($filter) as $report) + foreach ($this->reports->where($filter) as $report) { yield new Report($report); + } } - - use \Nette\SmartObject; } diff --git a/Web/Models/Repositories/Repository.php b/Web/Models/Repositories/Repository.php index fe3d6afe..e3333c9e 100644 --- a/Web/Models/Repositories/Repository.php +++ b/Web/Models/Repositories/Repository.php @@ -1,46 +1,50 @@ -context = DatabaseConnection::i()->getContext(); $this->table = $this->context->table($this->tableName); } - - function toEntity(?ActiveRow $ar) + + public function toEntity(?ActiveRow $ar) { $entityName = "openvk\\Web\\Models\\Entities\\$this->modelName"; - return is_null($ar) ? NULL : new $entityName($ar); + return is_null($ar) ? null : new $entityName($ar); } - - function get(int $id) + + public function get(int $id) { return $this->toEntity($this->table->get($id)); } - - function size(bool $withDeleted = false): int + + public function size(bool $withDeleted = false): int { return sizeof($this->table->where("deleted", $withDeleted)); } - - function enumerate(int $page, ?int $perPage = NULL, bool $withDeleted = false): \Traversable + + public function enumerate(int $page, ?int $perPage = null, bool $withDeleted = false): \Traversable { $perPage ??= OPENVK_DEFAULT_PER_PAGE; - - foreach($this->table->where("deleted", $withDeleted)->page($page, $perPage) as $entity) + + foreach ($this->table->where("deleted", $withDeleted)->page($page, $perPage) as $entity) { yield $this->toEntity($entity); + } } - - use \Nette\SmartObject; } diff --git a/Web/Models/Repositories/Restores.php b/Web/Models/Repositories/Restores.php index df9105a8..372ad16d 100644 --- a/Web/Models/Repositories/Restores.php +++ b/Web/Models/Repositories/Restores.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->restores = $this->context->table("password_resets"); } - - function toPasswordReset(?ActiveRow $ar): ?PasswordReset + + public function toPasswordReset(?ActiveRow $ar): ?PasswordReset { - return is_null($ar) ? NULL : new PasswordReset($ar); + return is_null($ar) ? null : new PasswordReset($ar); } - - function getByToken(string $token): ?PasswordReset + + public function getByToken(string $token): ?PasswordReset { return $this->toPasswordReset($this->restores->where("key", $token)->fetch()); } - - function getLatestByUser(User $user): ?PasswordReset + + public function getLatestByUser(User $user): ?PasswordReset { return $this->toPasswordReset($this->restores->where("profile", $user->getId())->order("timestamp DESC")->fetch()); } diff --git a/Web/Models/Repositories/SupportAgents.php b/Web/Models/Repositories/SupportAgents.php index 7b3a1e7e..b0dfcbbc 100644 --- a/Web/Models/Repositories/SupportAgents.php +++ b/Web/Models/Repositories/SupportAgents.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->agents = $this->context->table("support_names"); @@ -17,16 +21,16 @@ class SupportAgents private function toAgent(?ActiveRow $ar) { - return is_null($ar) ? NULL : new SupportAgent($ar); + return is_null($ar) ? null : new SupportAgent($ar); } - function get(int $id): ?SupportAgent + public function get(int $id): ?SupportAgent { return $this->toAgent($this->agents->where("agent", $id)->fetch()); } - function isExists(int $id): bool + public function isExists(int $id): bool { return !is_null($this->get($id)); } -} \ No newline at end of file +} diff --git a/Web/Models/Repositories/SupportAliases.php b/Web/Models/Repositories/SupportAliases.php index cb1a2521..45f4ce3e 100644 --- a/Web/Models/Repositories/SupportAliases.php +++ b/Web/Models/Repositories/SupportAliases.php @@ -1,12 +1,15 @@ -toEntity($this->table->where("agent", $agent)->fetch()); } diff --git a/Web/Models/Repositories/TicketComments.php b/Web/Models/Repositories/TicketComments.php index ee05bb55..05d59fa1 100644 --- a/Web/Models/Repositories/TicketComments.php +++ b/Web/Models/Repositories/TicketComments.php @@ -1,39 +1,46 @@ -context = DatabaseConnection::i()->getContext(); $this->comments = $this->context->table("tickets_comments"); } - - function getCommentsById(int $ticket_id): \Traversable + + public function getCommentsById(int $ticket_id): \Traversable { - foreach($this->comments->where(['ticket_id' => $ticket_id, 'deleted' => 0]) as $comment) yield new TicketComment($comment); + foreach ($this->comments->where(['ticket_id' => $ticket_id, 'deleted' => 0]) as $comment) { + yield new TicketComment($comment); + } } - function get(int $id): ?TicketComment + public function get(int $id): ?TicketComment { - $comment = $this->comments->get($id);; - if (!is_null($comment)) + $comment = $this->comments->get($id); + ; + if (!is_null($comment)) { return new TicketComment($comment); - else - return NULL; + } else { + return null; + } } - function getCountByAgent(int $agent_id, int $mark = NULL): int + public function getCountByAgent(int $agent_id, int $mark = null): int { $filter = ['user_id' => $agent_id, 'user_type' => 1]; $mark && $filter['mark'] = $mark; return sizeof($this->comments->where($filter)); } - - use \Nette\SmartObject; } diff --git a/Web/Models/Repositories/Tickets.php b/Web/Models/Repositories/Tickets.php index 1e84ebd8..dd7379c8 100644 --- a/Web/Models/Repositories/Tickets.php +++ b/Web/Models/Repositories/Tickets.php @@ -1,63 +1,71 @@ -context = DatabaseConnection::i()->getContext(); $this->tickets = $this->context->table("tickets"); } - + private function toTicket(?ActiveRow $ar): ?Ticket { - return is_null($ar) ? NULL : new Ticket($ar); + return is_null($ar) ? null : new Ticket($ar); } - - function getTickets(int $state = 0, int $page = 1): \Traversable + + public function getTickets(int $state = 0, int $page = 1): \Traversable { - foreach($this->tickets->where(["deleted" => 0, "type" => $state])->order("created DESC")->page($page, OPENVK_DEFAULT_PER_PAGE) as $ticket) + foreach ($this->tickets->where(["deleted" => 0, "type" => $state])->order("created DESC")->page($page, OPENVK_DEFAULT_PER_PAGE) as $ticket) { yield new Ticket($ticket); + } } - - function getTicketCount(int $state = 0): int + + public function getTicketCount(int $state = 0): int { return sizeof($this->tickets->where(["deleted" => 0, "type" => $state])); } - - function getTicketsByUserId(int $userId, int $page = 1): \Traversable + + public function getTicketsByUserId(int $userId, int $page = 1): \Traversable { - foreach($this->tickets->where(["user_id" => $userId, "deleted" => 0])->order("created DESC")->page($page, OPENVK_DEFAULT_PER_PAGE) as $ticket) yield new Ticket($ticket); + foreach ($this->tickets->where(["user_id" => $userId, "deleted" => 0])->order("created DESC")->page($page, OPENVK_DEFAULT_PER_PAGE) as $ticket) { + yield new Ticket($ticket); + } } - function getTicketsCountByUserId(int $userId, int $type = NULL): int + public function getTicketsCountByUserId(int $userId, int $type = null): int { - if(is_null($type)) + if (is_null($type)) { return sizeof($this->tickets->where(["user_id" => $userId, "deleted" => 0])); - else + } else { return sizeof($this->tickets->where(["user_id" => $userId, "deleted" => 0, "type" => $type])); + } } - - function getRequestById(int $requestId): ?Ticket + + public function getRequestById(int $requestId): ?Ticket { $requests = $this->tickets->where(["id" => $requestId])->fetch(); - if(!is_null($requests)) + if (!is_null($requests)) { return new Req($requests); - else - return NULL; - + } else { + return null; + } + } - - function get(int $id): ?Ticket + + public function get(int $id): ?Ticket { return $this->toTicket($this->tickets->get($id)); } - - use \Nette\SmartObject; } diff --git a/Web/Models/Repositories/Topics.php b/Web/Models/Repositories/Topics.php index 1c176310..dc7dda26 100644 --- a/Web/Models/Repositories/Topics.php +++ b/Web/Models/Repositories/Topics.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->topics = $this->context->table("topics"); @@ -18,56 +22,59 @@ class Topics private function toTopic(?ActiveRow $ar): ?Topic { - return is_null($ar) ? NULL : new Topic($ar); + return is_null($ar) ? null : new Topic($ar); } - - function get(int $id): ?Topic + + public function get(int $id): ?Topic { return $this->toTopic($this->topics->get($id)); } - function getTopicById(int $club, int $topic): ?Topic + public function getTopicById(int $club, int $topic): ?Topic { return $this->toTopic($this->topics->where(["group" => $club, "virtual_id" => $topic, "deleted" => 0])->fetch()); } - - function getClubTopics(Club $club, int $page = 1, ?int $perPage = NULL): \Traversable + + public function getClubTopics(Club $club, int $page = 1, ?int $perPage = null): \Traversable { - $perPage = $perPage ?? OPENVK_DEFAULT_PER_PAGE; + $perPage ??= OPENVK_DEFAULT_PER_PAGE; # Get pinned topics first $query = "SELECT `id` FROM `topics` WHERE `pinned` = 1 AND `group` = ? AND `deleted` = 0 UNION SELECT `id` FROM `topics` WHERE `pinned` = 0 AND `group` = ? AND `deleted` = 0"; $query .= " LIMIT " . $perPage . " OFFSET " . ($page - 1) * $perPage; - foreach(DatabaseConnection::i()->getConnection()->query($query, $club->getId(), $club->getId()) as $topic) { + foreach (DatabaseConnection::i()->getConnection()->query($query, $club->getId(), $club->getId()) as $topic) { $topic = $this->get($topic->id); - if(!$topic) continue; - + if (!$topic) { + continue; + } + yield $topic; } } - - function getClubTopicsCount(Club $club): int + + public function getClubTopicsCount(Club $club): int { return sizeof($this->topics->where([ "group" => $club->getId(), - "deleted" => false + "deleted" => false, ])); } - function find(Club $club, string $query): \Traversable + public function find(Club $club, string $query): \Traversable { return new Util\EntityStream("Topic", $this->topics->where("title LIKE ? AND group = ? AND deleted = 0", "%$query%", $club->getId())); } - function getLastTopics(Club $club, ?int $count = NULL): \Traversable + public function getLastTopics(Club $club, ?int $count = null): \Traversable { $topics = $this->topics->where([ "group" => $club->getId(), - "deleted" => false + "deleted" => false, ])->page(1, $count ?? OPENVK_DEFAULT_PER_PAGE)->order("created DESC"); - - foreach($topics as $topic) + + foreach ($topics as $topic) { yield $this->toTopic($topic); + } } } diff --git a/Web/Models/Repositories/Users.php b/Web/Models/Repositories/Users.php index ed5a87a5..407cc851 100644 --- a/Web/Models/Repositories/Users.php +++ b/Web/Models/Repositories/Users.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->users = $this->context->table("profiles"); $this->aliases = $this->context->table("aliases"); } - + private function toUser(?ActiveRow $ar): ?User { - return is_null($ar) ? NULL : new User($ar); + return is_null($ar) ? null : new User($ar); } - - function get(int $id): ?User + + public function get(int $id): ?User { return $this->toUser($this->users->get($id)); } - function getByIds(array $ids = []): array + public function getByIds(array $ids = []): array { $users = $this->users->select('*')->where('id IN (?)', $ids); $users_array = []; - foreach($users as $user) { + foreach ($users as $user) { $users_array[] = $this->toUser($user); } return $users_array; } - - function getByShortURL(string $url): ?User + + public function getByShortURL(string $url): ?User { $shortcode = $this->toUser($this->users->where("shortcode", $url)->fetch()); - if ($shortcode) + if ($shortcode) { return $shortcode; + } - $alias = (new Aliases)->getByShortcode($url); + $alias = (new Aliases())->getByShortcode($url); + + if (!$alias) { + return null; + } + if ($alias->getType() !== "user") { + return null; + } - if (!$alias) return NULL; - if ($alias->getType() !== "user") return NULL; - return $alias->getUser(); } - - function getByChandlerUserId(string $cid): ?User + + public function getByChandlerUserId(string $cid): ?User { return $this->toUser($this->users->where("user", $cid)->fetch()); } - - function getByChandlerUser(?ChandlerUser $user): ?User + + public function getByChandlerUser(?ChandlerUser $user): ?User { - return $user ? $this->getByChandlerUserId($user->getId()) : NULL; + return $user ? $this->getByChandlerUserId($user->getId()) : null; } - - function find(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream + + public function find(string $query, array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream { $query = "%$query%"; $result = $this->users->where("CONCAT_WS(' ', first_name, last_name, pseudo, shortcode) LIKE ?", $query)->where("deleted", 0); $order_str = 'id'; - switch($order['type']) { + switch ($order['type']) { case 'id': case 'reg_date': $order_str = 'id ' . ($order['invert'] ? 'ASC' : 'DESC'); @@ -82,10 +92,12 @@ class Users break; } - foreach($params as $paramName => $paramValue) { - if(is_null($paramValue) || $paramValue == '') continue; + foreach ($params as $paramName => $paramValue) { + if (is_null($paramValue) || $paramValue == '') { + continue; + } - switch($paramName) { + switch ($paramName) { case "hometown": $result->where("hometown LIKE ?", "%$paramValue%"); break; @@ -120,7 +132,9 @@ class Users $result->where("UNIX_TIMESTAMP(since) > ?", $paramValue); break; case "gender": - if((int) $paramValue == 3) break; + if ((int) $paramValue == 3) { + break; + } $result->where("sex ?", (int) $paramValue); break; case "ignore_id": @@ -132,13 +146,14 @@ class Users } } - if($order_str) + if ($order_str) { $result->order($order_str); + } return new Util\EntityStream("User", $result); } - - function getStatistics(): object + + public function getStatistics(): object { return (object) [ "all" => (clone $this->users)->count('*'), @@ -147,18 +162,22 @@ class Users ]; } - function getByAddress(string $address): ?User + public function getByAddress(string $address): ?User { - if(substr_compare($address, "/", -1) === 0) + if (substr_compare($address, "/", -1) === 0) { $address = substr($address, 0, iconv_strlen($address) - 1); + } $serverUrl = ovk_scheme(true) . $_SERVER["SERVER_NAME"]; - if(strpos($address, $serverUrl . "/") === 0) + if (strpos($address, $serverUrl . "/") === 0) { $address = substr($address, iconv_strlen($serverUrl) + 1); + } - if(strpos($address, "id") === 0) { + if (strpos($address, "id") === 0) { $user = $this->get((int) substr($address, 2)); - if($user) return $user; + if ($user) { + return $user; + } } return $this->getByShortUrl($address); @@ -168,19 +187,19 @@ class Users * If you need to check if the user is an instance administrator, use `$user->getChandlerUser()->can("access")->model("admin")->whichBelongsTo(NULL)`. * This method is more suitable for instance administrators lists */ - function getInstanceAdmins(bool $excludeHidden = true): \Traversable + public function getInstanceAdmins(bool $excludeHidden = true): \Traversable { $query = "SELECT DISTINCT(`profiles`.`id`) FROM `ChandlerACLRelations` JOIN `profiles` ON `ChandlerACLRelations`.`user` = `profiles`.`user` COLLATE utf8mb4_unicode_520_ci WHERE `ChandlerACLRelations`.`group` IN (SELECT `group` FROM `ChandlerACLGroupsPermissions` WHERE `model` = \"admin\" AND `permission` = \"access\")"; - if($excludeHidden) - $query .= " AND `ChandlerACLRelations`.`user` NOT IN (SELECT `user` FROM `ChandlerACLRelations` WHERE `group` IN (SELECT `group` FROM `ChandlerACLGroupsPermissions` WHERE `model` = \"hidden_admin\" AND `permission` = \"be\"))"; + if ($excludeHidden) { + $query .= " AND `ChandlerACLRelations`.`user` NOT IN (SELECT `user` FROM `ChandlerACLRelations` WHERE `group` IN (SELECT `group` FROM `ChandlerACLGroupsPermissions` WHERE `model` = \"hidden_admin\" AND `permission` = \"be\"))"; + } $query .= " ORDER BY `profiles`.`id`;"; $result = DatabaseConnection::i()->getConnection()->query($query); - foreach($result as $entry) + foreach ($result as $entry) { yield $this->get($entry->id); + } } - - use \Nette\SmartObject; } diff --git a/Web/Models/Repositories/Util/EntityStream.php b/Web/Models/Repositories/Util/EntityStream.php index dd8f317f..e281346f 100644 --- a/Web/Models/Repositories/Util/EntityStream.php +++ b/Web/Models/Repositories/Util/EntityStream.php @@ -1,18 +1,22 @@ -dbStream = $dbStream; $this->entityClass = $class[0] === "\\" ? $class : "openvk\\Web\\Models\\Entities\\$class"; } - + /** * Almost shorthand for (clone $this->dbStream) * Needed because it's used often in this class. And it's used often to prevent changing mutable dbStream. @@ -21,36 +25,37 @@ class EntityStream implements \IteratorAggregate { return (clone $this->dbStream); } - + private function getEntity(ActiveRow $result) { return new $this->entityClass($result); } - + private function stream(\Traversable $iterator): \Traversable { - foreach($iterator as $result) + foreach ($iterator as $result) { yield $this->getEntity($result); + } } - - function getIterator(): \Traversable + + public function getIterator(): \Traversable { trigger_error("Trying to use EntityStream as iterator directly. Are you sure this is what you want?", E_USER_WARNING); - + return $this->stream($this->dbs()); } - - function page(int $page, ?int $perPage = NULL): \Traversable + + public function page(int $page, ?int $perPage = null): \Traversable { return $this->stream($this->dbs()->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE)); } - - function offsetLimit(int $offset = 0, ?int $limit = NULL): \Traversable + + public function offsetLimit(int $offset = 0, ?int $limit = null): \Traversable { return $this->stream($this->dbs()->limit($limit ?? OPENVK_DEFAULT_PER_PAGE, $offset)); } - - function size(): int + + public function size(): int { return sizeof($this->dbs()); } diff --git a/Web/Models/Repositories/Verifications.php b/Web/Models/Repositories/Verifications.php index 83c13e59..9e6322ad 100755 --- a/Web/Models/Repositories/Verifications.php +++ b/Web/Models/Repositories/Verifications.php @@ -1,33 +1,37 @@ -context = DatabaseConnection::i()->getContext(); - $this->verifications = $this->context->table("email_verifications"); - } - - function toEmailVerification(?ActiveRow $ar): ?EmailVerification - { - return is_null($ar) ? NULL : new EmailVerification($ar); - } - - function getByToken(string $token): ?EmailVerification - { - return $this->toEmailVerification($this->verifications->where("key", $token)->fetch()); - } - - function getLatestByUser(User $user): ?EmailVerification - { - return $this->toEmailVerification($this->verifications->where("profile", $user->getId())->order("timestamp DESC")->fetch()); - } -} +context = DatabaseConnection::i()->getContext(); + $this->verifications = $this->context->table("email_verifications"); + } + + public function toEmailVerification(?ActiveRow $ar): ?EmailVerification + { + return is_null($ar) ? null : new EmailVerification($ar); + } + + public function getByToken(string $token): ?EmailVerification + { + return $this->toEmailVerification($this->verifications->where("key", $token)->fetch()); + } + + public function getLatestByUser(User $user): ?EmailVerification + { + return $this->toEmailVerification($this->verifications->where("profile", $user->getId())->order("timestamp DESC")->fetch()); + } +} diff --git a/Web/Models/Repositories/Videos.php b/Web/Models/Repositories/Videos.php index 8dbda7ab..de8e3d95 100644 --- a/Web/Models/Repositories/Videos.php +++ b/Web/Models/Repositories/Videos.php @@ -1,5 +1,9 @@ -context = DatabaseConnection::i()->getContext(); $this->videos = $this->context->table("videos"); } - - function get(int $id): ?Video + + public function get(int $id): ?Video { $videos = $this->videos->get($id); - if(!$videos) return NULL; - + if (!$videos) { + return null; + } + return new Video($videos); } - - function getByOwnerAndVID(int $owner, int $vId): ?Video + + public function getByOwnerAndVID(int $owner, int $vId): ?Video { $videos = $this->videos->where([ "owner" => $owner, "virtual_id" => $vId, ])->fetch(); - if(!$videos) return NULL; - + if (!$videos) { + return null; + } + return new Video($videos); } - - function getByUser(User $user, int $page = 1, ?int $perPage = NULL): \Traversable + + public function getByUser(User $user, int $page = 1, ?int $perPage = null): \Traversable { - $perPage = $perPage ?? OPENVK_DEFAULT_PER_PAGE; - foreach($this->videos->where("owner", $user->getId())->where(["deleted" => 0, "unlisted" => 0])->page($page, $perPage)->order("created DESC") as $video) - yield new Video($video); - } - - function getByUserLimit(User $user, int $offset = 0, int $limit = 10): \Traversable - { - $perPage = $perPage ?? OPENVK_DEFAULT_PER_PAGE; - foreach($this->videos->where("owner", $user->getId())->where(["deleted" => 0, "unlisted" => 0])->limit($limit, $offset)->order("created DESC") as $video) + $perPage ??= OPENVK_DEFAULT_PER_PAGE; + foreach ($this->videos->where("owner", $user->getId())->where(["deleted" => 0, "unlisted" => 0])->page($page, $perPage)->order("created DESC") as $video) { yield new Video($video); + } } - - function getUserVideosCount(User $user): int + + public function getByUserLimit(User $user, int $offset = 0, int $limit = 10): \Traversable + { + $perPage ??= OPENVK_DEFAULT_PER_PAGE; + foreach ($this->videos->where("owner", $user->getId())->where(["deleted" => 0, "unlisted" => 0])->limit($limit, $offset)->order("created DESC") as $video) { + yield new Video($video); + } + } + + public function getUserVideosCount(User $user): int { return sizeof($this->videos->where("owner", $user->getId())->where(["deleted" => 0, "unlisted" => 0])); } - function find(string $query = "", array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream + public function find(string $query = "", array $params = [], array $order = ['type' => 'id', 'invert' => false]): Util\EntityStream { $query = "%$query%"; $result = $this->videos->where("CONCAT_WS(' ', name, description) LIKE ?", $query)->where("deleted", 0)->where("unlisted", 0); $order_str = 'id'; - switch($order['type']) { + switch ($order['type']) { case 'id': $order_str = 'id ' . ($order['invert'] ? 'ASC' : 'DESC'); break; } - foreach($params as $paramName => $paramValue) { - switch($paramName) { + foreach ($params as $paramName => $paramValue) { + switch ($paramName) { case "before": $result->where("created < ?", $paramValue); break; @@ -74,19 +84,22 @@ class Videos $result->where("created > ?", $paramValue); break; case 'only_youtube': - if((int) $paramValue != 1) break; + if ((int) $paramValue != 1) { + break; + } $result->where("link != ?", 'NULL'); break; } } - if($order_str) + if ($order_str) { $result->order($order_str); + } return new Util\EntityStream("Video", $result); } - function getLastVideo(User $user) + public function getLastVideo(User $user) { $video = $this->videos->where("owner", $user->getId())->where(["deleted" => 0, "unlisted" => 0])->order("id DESC")->fetch(); diff --git a/Web/Models/Repositories/Vouchers.php b/Web/Models/Repositories/Vouchers.php index 62d0a54e..42e77417 100644 --- a/Web/Models/Repositories/Vouchers.php +++ b/Web/Models/Repositories/Vouchers.php @@ -1,19 +1,23 @@ -table->where([ "token" => $token, "deleted" => $withDeleted, ])->fetch(); - + return $this->toEntity($voucher); } } diff --git a/Web/Models/RowModel.php b/Web/Models/RowModel.php index 92baeaa6..4e20b317 100644 --- a/Web/Models/RowModel.php +++ b/Web/Models/RowModel.php @@ -1,7 +1,10 @@ -id = $id; } - - abstract function getThumbnailURL(): string; - - abstract function getURL(): string; - - abstract function getEmbed(string $w = "600", string $h = "340"): string; + + abstract public function getThumbnailURL(): string; + + abstract public function getURL(): string; + + abstract public function getEmbed(string $w = "600", string $h = "340"): string; } diff --git a/Web/Models/VideoDrivers/YouTubeVideoDriver.php b/Web/Models/VideoDrivers/YouTubeVideoDriver.php index 1b9940e6..95f50d47 100644 --- a/Web/Models/VideoDrivers/YouTubeVideoDriver.php +++ b/Web/Models/VideoDrivers/YouTubeVideoDriver.php @@ -1,29 +1,32 @@ -id/mqdefault.jpg"; } - - function getURL(): string + + public function getURL(): string { return "https://youtu.be/$this->id"; } - - function getEmbed(string $w = "600", string $h = "340"): string + + public function getEmbed(string $w = "600", string $h = "340"): string { return << -CODE; + + CODE; } } diff --git a/Web/Presenters/AboutPresenter.php b/Web/Presenters/AboutPresenter.php index 49ff1c32..9e8e975e 100644 --- a/Web/Presenters/AboutPresenter.php +++ b/Web/Presenters/AboutPresenter.php @@ -1,5 +1,9 @@ -user)) { - if($this->user->identity->getMainPage()) + if (!is_null($this->user)) { + if ($this->user->identity->getMainPage()) { $this->redirect("/feed"); - else + } else { $this->redirect($this->user->identity->getURL()); + } } - - if($_SERVER['REQUEST_URI'] == "/id0") { + + if ($_SERVER['REQUEST_URI'] == "/id0") { $this->redirect("/"); } - - $this->template->stats = (new Users)->getStatistics(); + + $this->template->stats = (new Users())->getStatistics(); } - - function renderRules(): void + + public function renderRules(): void { $this->pass("openvk!Support->knowledgeBaseArticle", "rules"); } - - function renderHelp(): void - {} - - function renderBB(): void - {} - function renderTour(): void - {} - - function renderInvite(): void + public function renderHelp(): void {} + + public function renderBB(): void {} + + public function renderTour(): void {} + + public function renderInvite(): void { $this->assertUserLoggedIn(); } - - function renderDonate(): void + + public function renderDonate(): void { $this->pass("openvk!Support->knowledgeBaseArticle", "donate"); } - - function renderPrivacy(): void + + public function renderPrivacy(): void { $this->pass("openvk!Support->knowledgeBaseArticle", "privacy"); } - - function renderVersion(): void + + public function renderVersion(): void { $this->template->themes = Themepacks::i()->getAllThemes(); $this->template->languages = getLanguages(); } - function renderAboutInstance(): void + public function renderAboutInstance(): void { - $this->template->usersStats = (new Users)->getStatistics(); - $this->template->clubsCount = (new Clubs)->getCount(); - $this->template->postsCount = (new Posts)->getCount(); + $this->template->usersStats = (new Users())->getStatistics(); + $this->template->clubsCount = (new Clubs())->getCount(); + $this->template->postsCount = (new Posts())->getCount(); $this->template->popularClubs = []; - $this->template->admins = iterator_to_array((new Users)->getInstanceAdmins()); + $this->template->admins = iterator_to_array((new Users())->getInstanceAdmins()); } - - function renderLanguage(): void + + public function renderLanguage(): void { $this->template->languages = getLanguages(); - - if(!is_null($_GET['lg'])){ + + if (!is_null($_GET['lg'])) { $this->assertNoCSRF(); setLanguage($_GET['lg']); } - if(!is_null($_GET['jReturnTo'])) + if (!is_null($_GET['jReturnTo'])) { $this->redirect(rawurldecode($_GET['jReturnTo'])); + } } - function renderExportJSLanguage($lg = NULL): void + public function renderExportJSLanguage($lg = null): void { $localizer = Localizator::i(); $lang = $lg; - if(is_null($lg)) + if (is_null($lg)) { $this->throwError(404, "Not found", "Language is not found"); + } header("Content-Type: application/javascript"); echo "window.lang = " . json_encode($localizer->export($lang)) . ";"; # привет хардкод :DDD exit; } - function renderSandbox(): void + public function renderSandbox(): void { $this->template->languages = getLanguages(); } - function renderRobotsTxt(): void + public function renderRobotsTxt(): void { $text = "# robots.txt file for openvk\n" . "#\n" @@ -109,10 +113,10 @@ final class AboutPresenter extends OpenVKPresenter . "# lack of rights to access the admin panel)\n\n" . "User-Agent: *\n" . "Disallow: /albums/create\n" - . "Disallow: /assets/packages/static/openvk/img/banned.jpg\n" - . "Disallow: /assets/packages/static/openvk/img/camera_200.png\n" - . "Disallow: /assets/packages/static/openvk/img/flags/\n" - . "Disallow: /assets/packages/static/openvk/img/oof.apng\n" + . "Disallow: /assets/packages/static/openvk/img/banned.jpg\n" + . "Disallow: /assets/packages/static/openvk/img/camera_200.png\n" + . "Disallow: /assets/packages/static/openvk/img/flags/\n" + . "Disallow: /assets/packages/static/openvk/img/oof.apng\n" . "Disallow: /videos/upload\n" . "Disallow: /invite\n" . "Disallow: /groups_create\n" @@ -137,13 +141,13 @@ final class AboutPresenter extends OpenVKPresenter exit($text); } - function renderHumansTxt(): void + public function renderHumansTxt(): void { # :D $this->redirect("https://github.com/openvk/openvk#readme"); } - function renderDev(): void + public function renderDev(): void { $this->redirect("https://docs.ovk.to/"); } diff --git a/Web/Presenters/AdminPresenter.php b/Web/Presenters/AdminPresenter.php index b8f480ca..ac3aa267 100644 --- a/Web/Presenters/AdminPresenter.php +++ b/Web/Presenters/AdminPresenter.php @@ -1,5 +1,9 @@ -users = $users; $this->clubs = $clubs; @@ -42,25 +46,27 @@ final class AdminPresenter extends OpenVKPresenter parent::__construct(); } - + private function warnIfNoCommerce(): void { - if(!OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"]) + if (!OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"]) { $this->flash("warn", tr("admin_commerce_disabled"), tr("admin_commerce_disabled_desc")); + } } private function warnIfLongpoolBroken(): void { bdump(is_writable(CHANDLER_ROOT . '/tmp/events.bin')); - if(file_exists(CHANDLER_ROOT . '/tmp/events.bin') == false || is_writable(CHANDLER_ROOT . '/tmp/events.bin') == false) + if (file_exists(CHANDLER_ROOT . '/tmp/events.bin') == false || is_writable(CHANDLER_ROOT . '/tmp/events.bin') == false) { $this->flash("warn", tr("admin_longpool_broken"), tr("admin_longpool_broken_desc", CHANDLER_ROOT . '/tmp/events.bin')); + } } - + private function searchResults(object $repo, &$count) { $query = $this->queryParam("q") ?? ""; $page = (int) ($this->queryParam("p") ?? 1); - + $count = $repo->find($query)->size(); return $repo->find($query)->page($page, 20); } @@ -73,56 +79,61 @@ final class AdminPresenter extends OpenVKPresenter $count = $this->audios->findPlaylists($query)->size(); return $this->audios->findPlaylists($query)->page($page, 20); } - - function onStartup(): void + + public function onStartup(): void { parent::onStartup(); - + $this->assertPermission("admin", "access", -1); } - - function renderIndex(): void + + public function renderIndex(): void { $this->warnIfLongpoolBroken(); } - - function renderUsers(): void + + public function renderUsers(): void { $this->template->users = $this->searchResults($this->users, $this->template->count); } - - function renderUser(int $id): void + + public function renderUser(int $id): void { $user = $this->users->get($id); - if(!$user) + if (!$user) { $this->notFound(); - + } + $this->template->user = $user; - $this->template->c_groups_list = (new ChandlerGroups)->getList(); + $this->template->c_groups_list = (new ChandlerGroups())->getList(); $this->template->c_memberships = $this->chandlerGroups->getUsersMemberships($user->getChandlerGUID()); - if($_SERVER["REQUEST_METHOD"] !== "POST") + if ($_SERVER["REQUEST_METHOD"] !== "POST") { return; - - switch($_POST["act"] ?? "info") { + } + + switch ($_POST["act"] ?? "info") { default: case "info": $user->setFirst_Name($this->postParam("first_name")); $user->setLast_Name($this->postParam("last_name")); $user->setPseudo($this->postParam("nickname")); $user->setStatus($this->postParam("status")); - if(!$user->setShortCode(empty($this->postParam("shortcode")) ? NULL : $this->postParam("shortcode"))) + if (!$user->setShortCode(empty($this->postParam("shortcode")) ? null : $this->postParam("shortcode"))) { $this->flash("err", tr("error"), tr("error_shorturl_incorrect")); + } $user->changeEmail($this->postParam("email")); - if($user->onlineStatus() != $this->postParam("online")) $user->setOnline(intval($this->postParam("online"))); + if ($user->onlineStatus() != $this->postParam("online")) { + $user->setOnline(intval($this->postParam("online"))); + } $user->setVerified(empty($this->postParam("verify") ? 0 : 1)); - if($this->postParam("add-to-group")) { - if (!(new ChandlerGroups)->isUserAMember($user->getChandlerGUID(), $this->postParam("add-to-group"))) { + if ($this->postParam("add-to-group")) { + if (!(new ChandlerGroups())->isUserAMember($user->getChandlerGUID(), $this->postParam("add-to-group"))) { $query = "INSERT INTO `ChandlerACLRelations` (`user`, `group`) VALUES ('" . $user->getChandlerGUID() . "', '" . $this->postParam("add-to-group") . "')"; DatabaseConnection::i()->getConnection()->query($query); } } - if($this->postParam("password")) { + if ($this->postParam("password")) { $user->getChandlerUser()->updatePassword($this->postParam("password")); } @@ -131,28 +142,30 @@ final class AdminPresenter extends OpenVKPresenter break; } } - - function renderClubs(): void + + public function renderClubs(): void { $this->template->clubs = $this->searchResults($this->clubs, $this->template->count); } - - function renderClub(int $id): void + + public function renderClub(int $id): void { $club = $this->clubs->get($id); - if(!$club) + if (!$club) { $this->notFound(); - + } + $this->template->mode = in_array($this->queryParam("act"), ["main", "ban", "followers"]) ? $this->queryParam("act") : "main"; $this->template->club = $club; $this->template->followers = $this->template->club->getFollowers((int) ($this->queryParam("p") ?? 1)); - if($_SERVER["REQUEST_METHOD"] !== "POST") + if ($_SERVER["REQUEST_METHOD"] !== "POST") { return; - - switch($this->queryParam("act")) { + } + + switch ($this->queryParam("act")) { default: case "main": $club->setOwner($this->postParam("id_owner")); @@ -165,175 +178,188 @@ final class AdminPresenter extends OpenVKPresenter $club->save(); break; case "ban": - $reason = mb_strlen(trim($this->postParam("ban_reason"))) > 0 ? $this->postParam("ban_reason") : NULL; + $reason = mb_strlen(trim($this->postParam("ban_reason"))) > 0 ? $this->postParam("ban_reason") : null; $club->setBlock_reason($reason); $club->save(); break; } } - - function renderVouchers(): void + + public function renderVouchers(): void { $this->warnIfNoCommerce(); - + $this->template->count = $this->vouchers->size(); $this->template->vouchers = iterator_to_array($this->vouchers->enumerate((int) ($this->queryParam("p") ?? 1))); } - - function renderVoucher(int $id): void + + public function renderVoucher(int $id): void { $this->warnIfNoCommerce(); - - $voucher = NULL; + + $voucher = null; $this->template->form = (object) []; - if($id === 0) { + if ($id === 0) { $this->template->form->id = 0; - $this->template->form->token = NULL; + $this->template->form->token = null; $this->template->form->coins = 0; $this->template->form->rating = 0; $this->template->form->usages = -1; $this->template->form->users = []; } else { $voucher = $this->vouchers->get($id); - if(!$voucher) + if (!$voucher) { $this->notFound(); - + } + $this->template->form->id = $voucher->getId(); $this->template->form->token = $voucher->getToken(); $this->template->form->coins = $voucher->getCoins(); $this->template->form->rating = $voucher->getRating(); $this->template->form->usages = $voucher->getRemainingUsages(); $this->template->form->users = iterator_to_array($voucher->getUsers()); - - if($this->template->form->usages === INF) + + if ($this->template->form->usages === INF) { $this->template->form->usages = -1; - else + } else { $this->template->form->usages = (int) $this->template->form->usages; + } } - - if($_SERVER["REQUEST_METHOD"] !== "POST") + + if ($_SERVER["REQUEST_METHOD"] !== "POST") { return; - - $voucher ??= new Voucher; + } + + $voucher ??= new Voucher(); $voucher->setCoins((int) $this->postParam("coins")); $voucher->setRating((int) $this->postParam("rating")); $voucher->setRemainingUsages($this->postParam("usages") === '-1' ? INF : ((int) $this->postParam("usages"))); - if(!empty($tok = $this->postParam("token")) && strlen($tok) === 24) + if (!empty($tok = $this->postParam("token")) && strlen($tok) === 24) { $voucher->setToken($tok); - + } + $voucher->save(); - + $this->redirect("/admin/vouchers/id" . $voucher->getId()); } - - function renderGiftCategories(): void + + public function renderGiftCategories(): void { $this->warnIfNoCommerce(); - + $this->template->act = $this->queryParam("act") ?? "list"; - $this->template->categories = iterator_to_array($this->gifts->getCategories((int) ($this->queryParam("p") ?? 1), NULL, $this->template->count)); + $this->template->categories = iterator_to_array($this->gifts->getCategories((int) ($this->queryParam("p") ?? 1), null, $this->template->count)); } - - function renderGiftCategory(string $slug, int $id): void + + public function renderGiftCategory(string $slug, int $id): void { $this->warnIfNoCommerce(); - + $cat; $gen = false; - if($id !== 0) { + if ($id !== 0) { $cat = $this->gifts->getCat($id); - if(!$cat) + if (!$cat) { $this->notFound(); - else if($cat->getSlug() !== $slug) + } elseif ($cat->getSlug() !== $slug) { $this->redirect("/admin/gifts/" . $cat->getSlug() . "." . $id . ".meta"); + } } else { $gen = true; - $cat = new GiftCategory; + $cat = new GiftCategory(); } - + $this->template->form = (object) []; $this->template->form->id = $id; $this->template->form->languages = []; - foreach(getLanguages() as $language) { + foreach (getLanguages() as $language) { $language = (object) $language; $this->template->form->languages[$language->code] = (object) []; - + $this->template->form->languages[$language->code]->name = $gen ? "" : ($cat->getName($language->code, true) ?? ""); $this->template->form->languages[$language->code]->description = $gen ? "" : ($cat->getDescription($language->code, true) ?? ""); } - + $this->template->form->languages["master"] = (object) [ "name" => $gen ? "Unknown Name" : $cat->getName(), - "description" => $gen ? "" : $cat->getDescription(), + "description" => $gen ? "" : $cat->getDescription(), ]; - - if($_SERVER["REQUEST_METHOD"] !== "POST") + + if ($_SERVER["REQUEST_METHOD"] !== "POST") { return; - - if($gen) { - $cat->setAutoQuery(NULL); + } + + if ($gen) { + $cat->setAutoQuery(null); $cat->save(); } - + $cat->setName("_", $this->postParam("name_master")); $cat->setDescription("_", $this->postParam("description_master")); - foreach(getLanguages() as $language) { + foreach (getLanguages() as $language) { $code = $language["code"]; - if(!empty($this->postParam("name_$code") ?? NULL)) + if (!empty($this->postParam("name_$code") ?? null)) { $cat->setName($code, $this->postParam("name_$code")); - - if(!empty($this->postParam("description_$code") ?? NULL)) + } + + if (!empty($this->postParam("description_$code") ?? null)) { $cat->setDescription($code, $this->postParam("description_$code")); + } } - + $this->redirect("/admin/gifts/" . $cat->getSlug() . "." . $cat->getId() . ".meta"); } - - function renderGifts(string $catSlug, int $catId): void + + public function renderGifts(string $catSlug, int $catId): void { $this->warnIfNoCommerce(); - + $cat = $this->gifts->getCat($catId); - if(!$cat) + if (!$cat) { $this->notFound(); - else if($cat->getSlug() !== $catSlug) + } elseif ($cat->getSlug() !== $catSlug) { $this->redirect("/admin/gifts/" . $cat->getSlug() . "." . $catId . "/"); - + } + $this->template->cat = $cat; - $this->template->gifts = iterator_to_array($cat->getGifts((int) ($this->queryParam("p") ?? 1), NULL, $this->template->count)); + $this->template->gifts = iterator_to_array($cat->getGifts((int) ($this->queryParam("p") ?? 1), null, $this->template->count)); } - - function renderGift(int $id): void + + public function renderGift(int $id): void { $this->warnIfNoCommerce(); - + $gift = $this->gifts->get($id); $act = $this->queryParam("act") ?? "edit"; - switch($act) { + switch ($act) { case "delete": $this->assertNoCSRF(); - if(!$gift) + if (!$gift) { $this->notFound(); - + } + $gift->delete(); $this->flashFail("succ", tr("admin_gift_moved_successfully"), tr("admin_gift_moved_to_recycle")); break; case "copy": case "move": $this->assertNoCSRF(); - if(!$gift) + if (!$gift) { $this->notFound(); - + } + $catFrom = $this->gifts->getCat((int) ($this->queryParam("from") ?? 0)); $catTo = $this->gifts->getCat((int) ($this->queryParam("to") ?? 0)); - if(!$catFrom || !$catTo || !$catFrom->hasGift($gift)) + if (!$catFrom || !$catTo || !$catFrom->hasGift($gift)) { $this->badRequest(); - - if($act === "move") + } + + if ($act === "move") { $catFrom->removeGift($gift); - + } + $catTo->addGift($gift); - + $name = $catTo->getName(); $this->flash("succ", tr("admin_gift_moved_successfully"), "This gift will now be in $name."); $this->redirect("/admin/gifts/" . $catTo->getSlug() . "." . $catTo->getId() . "/"); @@ -341,126 +367,133 @@ final class AdminPresenter extends OpenVKPresenter default: case "edit": $gen = false; - if(!$gift) { + if (!$gift) { $gen = true; - $gift = new Gift; + $gift = new Gift(); } - + $this->template->form = (object) []; $this->template->form->id = $id; $this->template->form->name = $gen ? "New Gift (1)" : $gift->getName(); - $this->template->form->price = $gen ? 0 : $gift->getPrice(); - $this->template->form->usages = $gen ? 0 : $gift->getUsages(); - $this->template->form->limit = $gen ? -1 : ($gift->getLimit() === INF ? -1 : $gift->getLimit()); - $this->template->form->pic = $gen ? NULL : $gift->getImage(Gift::IMAGE_URL); - - if($_SERVER["REQUEST_METHOD"] !== "POST") + $this->template->form->price = $gen ? 0 : $gift->getPrice(); + $this->template->form->usages = $gen ? 0 : $gift->getUsages(); + $this->template->form->limit = $gen ? -1 : ($gift->getLimit() === INF ? -1 : $gift->getLimit()); + $this->template->form->pic = $gen ? null : $gift->getImage(Gift::IMAGE_URL); + + if ($_SERVER["REQUEST_METHOD"] !== "POST") { return; - + } + $limit = $this->postParam("limit") ?? $this->template->form->limit; $limit = $limit == "-1" ? INF : (float) $limit; $gift->setLimit($limit, is_null($this->postParam("reset_limit")) ? Gift::PERIOD_SET_IF_NONE : Gift::PERIOD_SET); - + $gift->setName($this->postParam("name")); $gift->setPrice((int) $this->postParam("price")); $gift->setUsages((int) $this->postParam("usages")); - if(isset($_FILES["pic"]) && $_FILES["pic"]["error"] === UPLOAD_ERR_OK) { - if(!$gift->setImage($_FILES["pic"]["tmp_name"])) + if (isset($_FILES["pic"]) && $_FILES["pic"]["error"] === UPLOAD_ERR_OK) { + if (!$gift->setImage($_FILES["pic"]["tmp_name"])) { $this->flashFail("err", tr("error_when_saving_gift"), tr("error_when_saving_gift_bad_image")); - } else if($gen) { + } + } elseif ($gen) { # If there's no gift pic but it's newly created $this->flashFail("err", tr("error_when_saving_gift"), tr("error_when_saving_gift_no_image")); } - + $gift->save(); - - if($gen && !is_null($cat = $this->postParam("_cat"))) { + + if ($gen && !is_null($cat = $this->postParam("_cat"))) { $cat = $this->gifts->getCat((int) $cat); - if(!is_null($cat)) + if (!is_null($cat)) { $cat->addGift($gift); + } } - + $this->redirect("/admin/gifts/id" . $gift->getId()); } } - - function renderFiles(): void - { - - } - - function renderQuickBan(int $id): void + + public function renderFiles(): void {} + + public function renderQuickBan(int $id): void { $this->assertNoCSRF(); - if (str_contains($this->queryParam("reason"), "*")) + if (str_contains($this->queryParam("reason"), "*")) { exit(json_encode([ "error" => "Incorrect reason" ])); + } $unban_time = strtotime($this->queryParam("date")) ?: "permanent"; $user = $this->users->get($id); - if(!$user) + if (!$user) { exit(json_encode([ "error" => "User does not exist" ])); + } - if ($this->queryParam("incr")) + if ($this->queryParam("incr")) { $unban_time = time() + $user->getNewBanTime(); + } $user->ban($this->queryParam("reason"), true, $unban_time, $this->user->identity->getId()); exit(json_encode([ "success" => true, "reason" => $this->queryParam("reason") ])); } - function renderQuickUnban(int $id): void + public function renderQuickUnban(int $id): void { $this->assertNoCSRF(); - - $user = $this->users->get($id); - if(!$user) - exit(json_encode([ "error" => "User does not exist" ])); - $ban = (new Bans)->get((int)$user->getRawBanReason()); - if (!$ban || $ban->isOver()) + $user = $this->users->get($id); + if (!$user) { + exit(json_encode([ "error" => "User does not exist" ])); + } + + $ban = (new Bans())->get((int) $user->getRawBanReason()); + if (!$ban || $ban->isOver()) { exit(json_encode([ "error" => "User is not banned" ])); + } $ban->setRemoved_Manually(true); $ban->setRemoved_By($this->user->identity->getId()); $ban->save(); - $user->setBlock_Reason(NULL); + $user->setBlock_Reason(null); // $user->setUnblock_time(NULL); $user->save(); exit(json_encode([ "success" => true ])); } - - function renderQuickWarn(int $id): void + + public function renderQuickWarn(int $id): void { $this->assertNoCSRF(); - + $user = $this->users->get($id); - if(!$user) + if (!$user) { exit(json_encode([ "error" => "User does not exist" ])); - + } + $user->adminNotify("⚠️ " . $this->queryParam("message")); exit(json_encode([ "message" => $this->queryParam("message") ])); } - function renderBannedLinks(): void + public function renderBannedLinks(): void { $this->template->links = $this->bannedLinks->getList((int) $this->queryParam("p") ?: 1); - $this->template->users = new Users; + $this->template->users = new Users(); } - function renderBannedLink(int $id): void + public function renderBannedLink(int $id): void { $this->template->form = (object) []; - if($id === 0) { + if ($id === 0) { $this->template->form->id = 0; - $this->template->form->link = NULL; - $this->template->form->reason = NULL; + $this->template->form->link = null; + $this->template->form->reason = null; } else { - $link = (new BannedLinks)->get($id); - if(!$link) + $link = (new BannedLinks())->get($id); + if (!$link) { $this->notFound(); + } $this->template->form->id = $link->getId(); $this->template->form->link = $link->getDomain(); @@ -468,13 +501,14 @@ final class AdminPresenter extends OpenVKPresenter $this->template->form->regexp = $link->getRawRegexp(); } - if($_SERVER["REQUEST_METHOD"] !== "POST") + if ($_SERVER["REQUEST_METHOD"] !== "POST") { return; + } - $link = (new BannedLinks)->get($id); + $link = (new BannedLinks())->get($id); $new_domain = parse_url($this->postParam("link"))["host"]; - $new_reason = $this->postParam("reason") ?: NULL; + $new_reason = $this->postParam("reason") ?: null; $lid = $id; @@ -484,10 +518,11 @@ final class AdminPresenter extends OpenVKPresenter $link->setRegexp_rule($this->postParam("regexp")); $link->save(); } else { - if (!$new_domain) + if (!$new_domain) { $this->flashFail("err", tr("error"), tr("admin_banned_link_not_specified")); + } - $link = new BannedLink; + $link = new BannedLink(); $link->setDomain($new_domain); $link->setReason($new_reason); $link->setRegexp_rule($this->postParam("regexp")); @@ -500,45 +535,50 @@ final class AdminPresenter extends OpenVKPresenter $this->redirect("/admin/bannedLink/id" . $lid); } - function renderUnbanLink(int $id): void + public function renderUnbanLink(int $id): void { - $link = (new BannedLinks)->get($id); + $link = (new BannedLinks())->get($id); - if (!$link) + if (!$link) { $this->flashFail("err", tr("error"), tr("admin_banned_link_not_found")); + } $link->delete(false); $this->redirect("/admin/bannedLinks"); } - function renderBansHistory(int $user_id) :void + public function renderBansHistory(int $user_id): void { - $user = (new Users)->get($user_id); - if (!$user) $this->notFound(); + $user = (new Users())->get($user_id); + if (!$user) { + $this->notFound(); + } - $this->template->bans = (new Bans)->getByUser($user_id); + $this->template->bans = (new Bans())->getByUser($user_id); } - function renderChandlerGroups(): void + public function renderChandlerGroups(): void { - $this->template->groups = (new ChandlerGroups)->getList(); + $this->template->groups = (new ChandlerGroups())->getList(); - if($_SERVER["REQUEST_METHOD"] !== "POST") + if ($_SERVER["REQUEST_METHOD"] !== "POST") { return; + } $req = "INSERT INTO `ChandlerGroups` (`name`) VALUES ('" . $this->postParam("name") . "')"; DatabaseConnection::i()->getConnection()->query($req); } - function renderChandlerGroup(string $UUID): void + public function renderChandlerGroup(string $UUID): void { $DB = DatabaseConnection::i()->getConnection(); - if(is_null($DB->query("SELECT * FROM `ChandlerGroups` WHERE `id` = '$UUID'")->fetch())) + if (is_null($DB->query("SELECT * FROM `ChandlerGroups` WHERE `id` = '$UUID'")->fetch())) { $this->flashFail("err", tr("error"), tr("c_group_not_found")); + } - $this->template->group = (new ChandlerGroups)->get($UUID); + $this->template->group = (new ChandlerGroups())->get($UUID); $this->template->mode = in_array( $this->queryParam("act"), [ @@ -547,28 +587,31 @@ final class AdminPresenter extends OpenVKPresenter "permissions", "removeMember", "removePermission", - "delete" - ]) ? $this->queryParam("act") : "main"; - $this->template->members = (new ChandlerGroups)->getMembersById($UUID); - $this->template->perms = (new ChandlerGroups)->getPermissionsById($UUID); + "delete", + ] + ) ? $this->queryParam("act") : "main"; + $this->template->members = (new ChandlerGroups())->getMembersById($UUID); + $this->template->perms = (new ChandlerGroups())->getPermissionsById($UUID); - if($this->template->mode == "removeMember") { + if ($this->template->mode == "removeMember") { $where = "`user` = '" . $this->queryParam("uid") . "' AND `group` = '$UUID'"; - if(is_null($DB->query("SELECT * FROM `ChandlerACLRelations` WHERE " . $where)->fetch())) + if (is_null($DB->query("SELECT * FROM `ChandlerACLRelations` WHERE " . $where)->fetch())) { $this->flashFail("err", tr("error"), tr("c_user_is_not_in_group")); + } $DB->query("DELETE FROM `ChandlerACLRelations` WHERE " . $where); $this->flashFail("succ", tr("changes_saved"), tr("c_user_removed_from_group")); - } elseif($this->template->mode == "removePermission") { - $where = "`model` = '" . trim(addslashes($this->queryParam("model"))) . "' AND `permission` = '". $this->queryParam("perm") ."' AND `group` = '$UUID'"; + } elseif ($this->template->mode == "removePermission") { + $where = "`model` = '" . trim(addslashes($this->queryParam("model"))) . "' AND `permission` = '" . $this->queryParam("perm") . "' AND `group` = '$UUID'"; - if(is_null($DB->query("SELECT * FROM `ChandlerACLGroupsPermissions WHERE $where`"))) + if (is_null($DB->query("SELECT * FROM `ChandlerACLGroupsPermissions WHERE $where`"))) { $this->flashFail("err", tr("error"), tr("c_permission_not_found")); + } $DB->query("DELETE FROM `ChandlerACLGroupsPermissions` WHERE $where"); $this->flashFail("succ", tr("changes_saved"), tr("c_permission_removed_from_group")); - } elseif($this->template->mode == "delete") { + } elseif ($this->template->mode == "delete") { $DB->query("DELETE FROM `ChandlerGroups` WHERE `id` = '$UUID'"); $DB->query("DELETE FROM `ChandlerACLGroupsPermissions` WHERE `group` = '$UUID'"); $DB->query("DELETE FROM `ChandlerACLRelations` WHERE `group` = '$UUID'"); @@ -576,58 +619,71 @@ final class AdminPresenter extends OpenVKPresenter $this->flashFail("succ", tr("changes_saved"), tr("c_group_removed")); } - if ($_SERVER["REQUEST_METHOD"] !== "POST") return; + if ($_SERVER["REQUEST_METHOD"] !== "POST") { + return; + } $req = ""; - if($this->template->mode == "main") - if($this->postParam("delete")) + if ($this->template->mode == "main") { + if ($this->postParam("delete")) { $req = "DELETE FROM `ChandlerGroups` WHERE `id`='$UUID'"; - else - $req = "UPDATE `ChandlerGroups` SET `name`='". $this->postParam('name') ."' , `color`='". $this->postParam("color") ."' WHERE `id`='$UUID'"; + } else { + $req = "UPDATE `ChandlerGroups` SET `name`='" . $this->postParam('name') . "' , `color`='" . $this->postParam("color") . "' WHERE `id`='$UUID'"; + } + } - if($this->template->mode == "members") - if($this->postParam("uid")) - if(!is_null($DB->query("SELECT * FROM `ChandlerACLRelations` WHERE `user` = '" . $this->postParam("uid") . "'"))) + if ($this->template->mode == "members") { + if ($this->postParam("uid")) { + if (!is_null($DB->query("SELECT * FROM `ChandlerACLRelations` WHERE `user` = '" . $this->postParam("uid") . "'"))) { $this->flashFail("err", tr("error"), tr("c_user_is_already_in_group")); + } + } + } - $req = "INSERT INTO `ChandlerACLRelations` (`user`, `group`, `priority`) VALUES ('". $this->postParam("uid") ."', '$UUID', 32)"; + $req = "INSERT INTO `ChandlerACLRelations` (`user`, `group`, `priority`) VALUES ('" . $this->postParam("uid") . "', '$UUID', 32)"; - if($this->template->mode == "permissions") - $req = "INSERT INTO `ChandlerACLGroupsPermissions` (`group`, `model`, `permission`, `context`) VALUES ('$UUID', '". trim(addslashes($this->postParam("model"))) ."', '". $this->postParam("permission") ."', 0)"; + if ($this->template->mode == "permissions") { + $req = "INSERT INTO `ChandlerACLGroupsPermissions` (`group`, `model`, `permission`, `context`) VALUES ('$UUID', '" . trim(addslashes($this->postParam("model"))) . "', '" . $this->postParam("permission") . "', 0)"; + } $DB->query($req); $this->flashFail("succ", tr("changes_saved")); } - function renderChandlerUser(string $UUID): void + public function renderChandlerUser(string $UUID): void { - if(!$UUID) $this->notFound(); + if (!$UUID) { + $this->notFound(); + } $c_user = (new ChandlerUsers())->getById($UUID); $user = $this->users->getByChandlerUser($c_user); - if(!$user) $this->notFound(); + if (!$user) { + $this->notFound(); + } $this->redirect("/admin/users/id" . $user->getId()); } - function renderMusic(): void + public function renderMusic(): void { $this->template->mode = in_array($this->queryParam("act"), ["audios", "playlists"]) ? $this->queryParam("act") : "audios"; - if ($this->template->mode === "audios") + if ($this->template->mode === "audios") { $this->template->audios = $this->searchResults($this->audios, $this->template->count); - else + } else { $this->template->playlists = $this->searchPlaylists($this->template->count); + } } - function renderEditMusic(int $audio_id): void + public function renderEditMusic(int $audio_id): void { $audio = $this->audios->get($audio_id); $this->template->audio = $audio; try { $this->template->owner = $audio->getOwner()->getId(); - } catch(\Throwable $e) { + } catch (\Throwable $e) { $this->template->owner = 1; } @@ -644,7 +700,7 @@ final class AdminPresenter extends OpenVKPresenter } } - function renderEditPlaylist(int $playlist_id): void + public function renderEditPlaylist(int $playlist_id): void { $playlist = $this->audios->getPlaylist($playlist_id); $this->template->playlist = $playlist; @@ -659,7 +715,7 @@ final class AdminPresenter extends OpenVKPresenter } } - function renderLogs(): void + public function renderLogs(): void { $filter = []; @@ -668,7 +724,7 @@ final class AdminPresenter extends OpenVKPresenter $filter["id"] = $id; $this->template->id = $id; } - if ($this->queryParam("type") !== NULL && $this->queryParam("type") !== "any") { + if ($this->queryParam("type") !== null && $this->queryParam("type") !== "any") { $type = in_array($this->queryParam("type"), [0, 1, 2, 3]) ? (int) $this->queryParam("type") : 0; $filter["type"] = $type; $this->template->type = $type; @@ -683,14 +739,14 @@ final class AdminPresenter extends OpenVKPresenter $filter["object_id"] = $obj_id; $this->template->obj_id = $obj_id; } - if ($this->queryParam("obj_type") !== NULL && $this->queryParam("obj_type") !== "any") { + if ($this->queryParam("obj_type") !== null && $this->queryParam("obj_type") !== "any") { $obj_type = "openvk\\Web\\Models\\Entities\\" . $this->queryParam("obj_type"); $filter["object_model"] = $obj_type; $this->template->obj_type = $obj_type; } - $logs = iterator_to_array((new Logs)->search($filter)); + $logs = iterator_to_array((new Logs())->search($filter)); $this->template->logs = $logs; - $this->template->object_types = (new Logs)->getTypes(); + $this->template->object_types = (new Logs())->getTypes(); } } diff --git a/Web/Presenters/AppsPresenter.php b/Web/Presenters/AppsPresenter.php index 8dcfb8a4..a621772a 100644 --- a/Web/Presenters/AppsPresenter.php +++ b/Web/Presenters/AppsPresenter.php @@ -1,5 +1,9 @@ -apps = $apps; - + parent::__construct(); } - - function renderPlay(int $app): void + + public function renderPlay(int $app): void { $this->assertUserLoggedIn(); - + $app = $this->apps->get($app); - if(!$app || !$app->isEnabled()) + if (!$app || !$app->isEnabled()) { $this->notFound(); - + } + $this->template->id = $app->getId(); $this->template->name = $app->getName(); $this->template->desc = $app->getDescription(); @@ -31,70 +36,78 @@ final class AppsPresenter extends OpenVKPresenter $this->template->news = $app->getNote(); $this->template->perms = $app->getPermissions($this->user->identity); } - - function renderUnInstall(): void + + public function renderUnInstall(): void { $this->assertUserLoggedIn(); $this->assertNoCSRF(); - + $app = $this->apps->get((int) $this->queryParam("app")); - if(!$app) + if (!$app) { $this->flashFail("err", tr("app_err_not_found"), tr("app_err_not_found_desc")); - + } + $app->uninstall($this->user->identity); $this->flashFail("succ", tr("app_uninstalled"), tr("app_uninstalled_desc")); } - - function renderEdit(): void + + public function renderEdit(): void { $this->assertUserLoggedIn(); - - $app = NULL; - if($this->queryParam("act") !== "create") { - if(empty($this->queryParam("app"))) + + $app = null; + if ($this->queryParam("act") !== "create") { + if (empty($this->queryParam("app"))) { $this->flashFail("err", tr("app_err_not_found"), tr("app_err_not_found_desc")); - + } + $app = $this->apps->get((int) $this->queryParam("app")); - if(!$app) + if (!$app) { $this->flashFail("err", tr("app_err_not_found"), tr("app_err_not_found_desc")); - - if($app->getOwner()->getId() != $this->user->identity->getId()) + } + + if ($app->getOwner()->getId() != $this->user->identity->getId()) { $this->flashFail("err", tr("forbidden"), tr("app_err_forbidden_desc")); + } } - - if($_SERVER["REQUEST_METHOD"] === "POST") { - if(!$app) { - $app = new Application; + + if ($_SERVER["REQUEST_METHOD"] === "POST") { + if (!$app) { + $app = new Application(); $app->setOwner($this->user->id); } - - if(!filter_var($this->postParam("url"), FILTER_VALIDATE_URL)) + + if (!filter_var($this->postParam("url"), FILTER_VALIDATE_URL)) { $this->flashFail("err", tr("app_err_url"), tr("app_err_url_desc")); - - if(isset($_FILES["ava"]) && $_FILES["ava"]["size"] > 0) { - if(($res = $app->setAvatar($_FILES["ava"])) !== 0) + } + + if (isset($_FILES["ava"]) && $_FILES["ava"]["size"] > 0) { + if (($res = $app->setAvatar($_FILES["ava"])) !== 0) { $this->flashFail("err", tr("app_err_ava"), tr("app_err_ava_desc", $res)); + } } - - if(empty($this->postParam("note"))) { - $app->setNoteLink(NULL); + + if (empty($this->postParam("note"))) { + $app->setNoteLink(null); } else { - if(!$app->setNoteLink($this->postParam("note"))) + if (!$app->setNoteLink($this->postParam("note"))) { $this->flashFail("err", tr("app_err_note"), tr("app_err_note_desc")); + } } - + $app->setName($this->postParam("name")); $app->setDescription($this->postParam("desc")); $app->setAddress($this->postParam("url")); - if($this->postParam("enable") === "on") + if ($this->postParam("enable") === "on") { $app->enable(); - else - $app->disable(); # no need to save since enable/disable will call save() internally - + } else { + $app->disable(); + } # no need to save since enable/disable will call save() internally + $this->redirect("/editapp?act=edit&app=" . $app->getId()); # will exit here } - - if(!is_null($app)) { + + if (!is_null($app)) { $this->template->create = false; $this->template->id = $app->getId(); $this->template->name = $app->getName(); @@ -109,30 +122,31 @@ final class AppsPresenter extends OpenVKPresenter $this->template->create = true; } } - - function renderList(): void + + public function renderList(): void { $this->assertUserLoggedIn(); - + $act = $this->queryParam("act"); - if(!in_array($act, ["list", "installed", "dev"])) + if (!in_array($act, ["list", "installed", "dev"])) { $act = "installed"; - + } + $page = (int) ($this->queryParam("p") ?? 1); - if($act == "list") { + if ($act == "list") { $apps = $this->apps->getList($page); $count = $this->apps->getListCount(); - } else if($act == "installed") { + } elseif ($act == "installed") { $apps = $this->apps->getInstalled($this->user->identity, $page); $count = $this->apps->getInstalledCount($this->user->identity); - } else if($act == "dev") { + } elseif ($act == "dev") { $apps = $this->apps->getByOwner($this->user->identity, $page); $count = $this->apps->getOwnCount($this->user->identity); } - + $this->template->act = $act; $this->template->iterator = $apps; $this->template->count = $count; $this->template->page = $page; } -} \ No newline at end of file +} diff --git a/Web/Presenters/AudioPresenter.php b/Web/Presenters/AudioPresenter.php index aa8801f5..db341f83 100644 --- a/Web/Presenters/AudioPresenter.php +++ b/Web/Presenters/AudioPresenter.php @@ -1,5 +1,9 @@ -audios = $audios; } - function renderPopular(): void + public function renderPopular(): void { - $this->renderList(NULL, "popular"); + $this->renderList(null, "popular"); } - function renderNew(): void + public function renderNew(): void { - $this->renderList(NULL, "new"); + $this->renderList(null, "new"); } - function renderList(?int $owner = NULL, ?string $mode = "list"): void + public function renderList(?int $owner = null, ?string $mode = "list"): void { $this->assertUserLoggedIn(); $this->template->_template = "Audio/List.xml"; - $page = (int)($this->queryParam("p") ?? 1); + $page = (int) ($this->queryParam("p") ?? 1); $audios = []; if ($mode === "list") { - $entity = NULL; + $entity = null; if ($owner < 0) { - $entity = (new Clubs)->get($owner * -1); - if (!$entity || $entity->isBanned()) + $entity = (new Clubs())->get($owner * -1); + if (!$entity || $entity->isBanned()) { $this->redirect("/audios" . $this->user->id); + } $audios = $this->audios->getByClub($entity, $page, 10); $audiosCount = $this->audios->getClubCollectionSize($entity); } else { - $entity = (new Users)->get($owner); - if (!$entity || $entity->isDeleted() || $entity->isBanned()) + $entity = (new Users())->get($owner); + if (!$entity || $entity->isDeleted() || $entity->isBanned()) { $this->redirect("/audios" . $this->user->id); + } - if(!$entity->getPrivacyPermission("audios.read", $this->user->identity)) + if (!$entity->getPrivacyPermission("audios.read", $this->user->identity)) { $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); + } $audios = $this->audios->getByUser($entity, $page, 10); $audiosCount = $this->audios->getUserCollectionSize($entity); } - if (!$entity) + if (!$entity) { $this->notFound(); + } $this->template->owner = $entity; $this->template->ownerId = $owner; - $this->template->club = $owner < 0 ? $entity : NULL; + $this->template->club = $owner < 0 ? $entity : null; $this->template->isMy = ($owner > 0 && ($entity->getId() === $this->user->id)); $this->template->isMyClub = ($owner < 0 && $entity->canBeModifiedBy($this->user->identity)); - } else if ($mode === "new") { + } elseif ($mode === "new") { $audios = $this->audios->getNew(); $audiosCount = $audios->size(); - } else if ($mode === "playlists") { - if($owner < 0) { - $entity = (new Clubs)->get(abs($owner)); - if (!$entity || $entity->isBanned()) + } elseif ($mode === "playlists") { + if ($owner < 0) { + $entity = (new Clubs())->get(abs($owner)); + if (!$entity || $entity->isBanned()) { $this->redirect("/playlists" . $this->user->id); + } $playlists = $this->audios->getPlaylistsByClub($entity, $page, OPENVK_DEFAULT_PER_PAGE); $playlistsCount = $this->audios->getClubPlaylistsCount($entity); } else { - $entity = (new Users)->get($owner); - if (!$entity || $entity->isDeleted() || $entity->isBanned()) + $entity = (new Users())->get($owner); + if (!$entity || $entity->isDeleted() || $entity->isBanned()) { $this->redirect("/playlists" . $this->user->id); + } - if(!$entity->getPrivacyPermission("audios.read", $this->user->identity)) + if (!$entity->getPrivacyPermission("audios.read", $this->user->identity)) { $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); + } $playlists = $this->audios->getPlaylistsByUser($entity, $page, OPENVK_DEFAULT_PER_PAGE); $playlistsCount = $this->audios->getUserPlaylistsCount($entity); @@ -94,10 +105,10 @@ final class AudioPresenter extends OpenVKPresenter $this->template->playlistsCount = $playlistsCount; $this->template->owner = $entity; $this->template->ownerId = $owner; - $this->template->club = $owner < 0 ? $entity : NULL; + $this->template->club = $owner < 0 ? $entity : null; $this->template->isMy = ($owner > 0 && ($entity->getId() === $this->user->id)); $this->template->isMyClub = ($owner < 0 && $entity->canBeModifiedBy($this->user->identity)); - } else if ($mode === 'alone_audio') { + } elseif ($mode === 'alone_audio') { $audios = [$this->template->alone_audio]; $audiosCount = 1; @@ -113,27 +124,28 @@ final class AudioPresenter extends OpenVKPresenter $this->template->mode = $mode; $this->template->page = $page; - - if(in_array($mode, ["list", "new", "popular"]) && $this->user->identity && $page < 2) + + if (in_array($mode, ["list", "new", "popular"]) && $this->user->identity && $page < 2) { $this->template->friendsAudios = $this->user->identity->getBroadcastList("all", true); + } } - function renderEmbed(int $owner, int $id): void + public function renderEmbed(int $owner, int $id): void { $audio = $this->audios->getByOwnerAndVID($owner, $id); - if(!$audio) { + if (!$audio) { header("HTTP/1.1 404 Not Found"); exit("" . tr("audio_embed_not_found") . "."); - } else if($audio->isDeleted()) { + } elseif ($audio->isDeleted()) { header("HTTP/1.1 410 Not Found"); exit("" . tr("audio_embed_deleted") . "."); - } else if($audio->isWithdrawn()) { + } elseif ($audio->isWithdrawn()) { header("HTTP/1.1 451 Unavailable for legal reasons"); exit("" . tr("audio_embed_withdrawn") . "."); - } else if(!$audio->canBeViewedBy(NULL)) { + } elseif (!$audio->canBeViewedBy(null)) { header("HTTP/1.1 403 Forbidden"); exit("" . tr("audio_embed_forbidden") . "."); - } else if(!$audio->isAvailable()) { + } elseif (!$audio->isAvailable()) { header("HTTP/1.1 425 Too Early"); exit("" . tr("audio_embed_processing") . "."); } @@ -141,56 +153,62 @@ final class AudioPresenter extends OpenVKPresenter $this->template->audio = $audio; } - function renderUpload(): void + public function renderUpload(): void { $this->assertUserLoggedIn(); - $group = NULL; - $playlist = NULL; + $group = null; + $playlist = null; $isAjax = $this->postParam("ajax", false) == 1; - if(!is_null($this->queryParam("gid")) && !is_null($this->queryParam("playlist"))) { + if (!is_null($this->queryParam("gid")) && !is_null($this->queryParam("playlist"))) { $this->flashFail("err", tr("forbidden"), tr("not_enough_permissions_comment"), null, $isAjax); } - if(!is_null($this->queryParam("gid"))) { + if (!is_null($this->queryParam("gid"))) { $gid = (int) $this->queryParam("gid"); - $group = (new Clubs)->get($gid); - if(!$group) + $group = (new Clubs())->get($gid); + if (!$group) { $this->flashFail("err", tr("forbidden"), tr("not_enough_permissions_comment"), null, $isAjax); + } - if(!$group->canUploadAudio($this->user->identity)) + if (!$group->canUploadAudio($this->user->identity)) { $this->flashFail("err", tr("forbidden"), tr("not_enough_permissions_comment"), null, $isAjax); + } } - if(!is_null($this->queryParam("playlist"))) { - $playlist_id = (int)$this->queryParam("playlist"); - $playlist = (new Audios)->getPlaylist($playlist_id); - if(!$playlist || $playlist->isDeleted()) + if (!is_null($this->queryParam("playlist"))) { + $playlist_id = (int) $this->queryParam("playlist"); + $playlist = (new Audios())->getPlaylist($playlist_id); + if (!$playlist || $playlist->isDeleted()) { $this->flashFail("err", tr("forbidden"), tr("not_enough_permissions_comment"), null, $isAjax); + } - if(!$playlist->canBeModifiedBy($this->user->identity)) + if (!$playlist->canBeModifiedBy($this->user->identity)) { $this->flashFail("err", tr("forbidden"), tr("not_enough_permissions_comment"), null, $isAjax); - + } + $this->template->playlist = $playlist; $this->template->owner = $playlist->getOwner(); } $this->template->group = $group; - if($_SERVER["REQUEST_METHOD"] !== "POST") + if ($_SERVER["REQUEST_METHOD"] !== "POST") { return; + } $upload = $_FILES["blob"]; - if(isset($upload) && file_exists($upload["tmp_name"])) { - if($upload["size"] > self::MAX_AUDIO_SIZE) + if (isset($upload) && file_exists($upload["tmp_name"])) { + if ($upload["size"] > self::MAX_AUDIO_SIZE) { $this->flashFail("err", tr("error"), tr("media_file_corrupted_or_too_large"), null, $isAjax); + } } else { $err = !isset($upload) ? 65536 : $upload["error"]; $err = str_pad(dechex($err), 9, "0", STR_PAD_LEFT); $readableError = tr("error_generic"); - switch($upload["error"]) { + switch ($upload["error"]) { default: case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: @@ -221,52 +239,55 @@ final class AudioPresenter extends OpenVKPresenter $nsfw = ($this->postParam("explicit") ?? "off") === "on"; $is_unlisted = ($this->postParam("unlisted") ?? "off") === "on"; - if(empty($performer) || empty($name) || iconv_strlen($performer . $name) > 128) # FQN of audio must not be more than 128 chars + if (empty($performer) || empty($name) || iconv_strlen($performer . $name) > 128) { # FQN of audio must not be more than 128 chars $this->flashFail("err", tr("error"), tr("error_insufficient_info"), null, $isAjax); + } - $audio = new Audio; + $audio = new Audio(); $audio->setOwner($this->user->id); $audio->setName($name); $audio->setPerformer($performer); - $audio->setLyrics(empty($lyrics) ? NULL : $lyrics); + $audio->setLyrics(empty($lyrics) ? null : $lyrics); $audio->setGenre($genre); $audio->setExplicit($nsfw); $audio->setUnlisted($is_unlisted); try { $audio->setFile($upload); - } catch(\DomainException $ex) { + } catch (\DomainException $ex) { $e = $ex->getMessage(); $this->flashFail("err", tr("error"), tr("media_file_corrupted_or_too_large") . " $e.", null, $isAjax); - } catch(\RuntimeException $ex) { + } catch (\RuntimeException $ex) { $this->flashFail("err", tr("error"), tr("ffmpeg_timeout"), null, $isAjax); - } catch(\BadMethodCallException $ex) { + } catch (\BadMethodCallException $ex) { $this->flashFail("err", tr("error"), "хз", null, $isAjax); - } catch(\Exception $ex) { + } catch (\Exception $ex) { $this->flashFail("err", tr("error"), tr("ffmpeg_not_installed"), null, $isAjax); } $audio->save(); - if($playlist) { + if ($playlist) { $playlist->add($audio); } else { $audio->add($group ?? $this->user->identity); } - if(!$isAjax) + if (!$isAjax) { $this->redirect(is_null($group) ? "/audios" . $this->user->id : "/audios-" . $group->getId()); - else { + } else { $redirectLink = "/audios"; - if(!is_null($group)) + if (!is_null($group)) { $redirectLink .= $group->getRealId(); - else + } else { $redirectLink .= $this->user->id; + } - if($playlist) + if ($playlist) { $redirectLink = "/playlist" . $playlist->getPrettyId(); - + } + $this->returnJson([ "success" => true, "redirect_link" => $redirectLink, @@ -274,43 +295,46 @@ final class AudioPresenter extends OpenVKPresenter } } - function renderAloneAudio(int $owner_id, int $audio_id): void + public function renderAloneAudio(int $owner_id, int $audio_id): void { $this->assertUserLoggedIn(); $found_audio = $this->audios->get($audio_id); - if(!$found_audio || $found_audio->isDeleted() || !$found_audio->canBeViewedBy($this->user->identity)) { + if (!$found_audio || $found_audio->isDeleted() || !$found_audio->canBeViewedBy($this->user->identity)) { $this->notFound(); } $this->template->alone_audio = $found_audio; - $this->renderList(NULL, 'alone_audio'); + $this->renderList(null, 'alone_audio'); } - function renderListen(int $id): void + public function renderListen(int $id): void { if ($_SERVER["REQUEST_METHOD"] === "POST") { $this->assertNoCSRF(); - if(is_null($this->user)) + if (is_null($this->user)) { $this->returnJson(["success" => false]); + } $audio = $this->audios->get($id); if ($audio && !$audio->isDeleted() && !$audio->isWithdrawn()) { - if(!empty($this->postParam("playlist"))) { - $playlist = (new Audios)->getPlaylist((int)$this->postParam("playlist")); + if (!empty($this->postParam("playlist"))) { + $playlist = (new Audios())->getPlaylist((int) $this->postParam("playlist")); - if(!$playlist || $playlist->isDeleted() || !$playlist->canBeViewedBy($this->user->identity) || !$playlist->hasAudio($audio)) - $playlist = NULL; + if (!$playlist || $playlist->isDeleted() || !$playlist->canBeViewedBy($this->user->identity) || !$playlist->hasAudio($audio)) { + $playlist = null; + } } $listen = $audio->listen($this->user->identity, $playlist); $returnArr = ["success" => $listen]; - - if($playlist) + + if ($playlist) { $returnArr["new_playlists_listens"] = $playlist->getListens(); + } $this->returnJson($returnArr); } @@ -321,12 +345,12 @@ final class AudioPresenter extends OpenVKPresenter } } - function renderSearch(): void + public function renderSearch(): void { $this->redirect("/search?section=audios"); } - function renderNewPlaylist(): void + public function renderNewPlaylist(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(true); @@ -334,9 +358,10 @@ final class AudioPresenter extends OpenVKPresenter $owner = $this->user->id; if ($this->requestParam("gid")) { - $club = (new Clubs)->get((int) abs((int)$this->requestParam("gid"))); - if (!$club || $club->isBanned() || !$club->canBeModifiedBy($this->user->identity)) + $club = (new Clubs())->get((int) abs((int) $this->requestParam("gid"))); + if (!$club || $club->isBanned() || !$club->canBeModifiedBy($this->user->identity)) { $this->redirect("/audios" . $this->user->id); + } $owner = ($club->getId() * -1); @@ -346,46 +371,50 @@ final class AudioPresenter extends OpenVKPresenter if ($_SERVER["REQUEST_METHOD"] === "POST") { $title = $this->postParam("title"); $description = $this->postParam("description"); - $is_unlisted = (int)$this->postParam('is_unlisted'); - $is_ajax = (int)$this->postParam('ajax') == 1; + $is_unlisted = (int) $this->postParam('is_unlisted'); + $is_ajax = (int) $this->postParam('ajax') == 1; $audios = array_slice(explode(",", $this->postParam("audios")), 0, 1000); - if(empty($title) || iconv_strlen($title) < 1) - $this->flashFail("err", tr("error"), tr("set_playlist_name"), NULL, $is_ajax); + if (empty($title) || iconv_strlen($title) < 1) { + $this->flashFail("err", tr("error"), tr("set_playlist_name"), null, $is_ajax); + } - $playlist = new Playlist; + $playlist = new Playlist(); $playlist->setOwner($owner); $playlist->setName(substr($title, 0, 125)); $playlist->setDescription(substr($description, 0, 2045)); - if($is_unlisted == 1) + if ($is_unlisted == 1) { $playlist->setUnlisted(true); - - if($_FILES["cover"]["error"] === UPLOAD_ERR_OK) { - if(!str_starts_with($_FILES["cover"]["type"], "image")) - $this->flashFail("err", tr("error"), tr("not_a_photo"), NULL, $is_ajax); + } + + if ($_FILES["cover"]["error"] === UPLOAD_ERR_OK) { + if (!str_starts_with($_FILES["cover"]["type"], "image")) { + $this->flashFail("err", tr("error"), tr("not_a_photo"), null, $is_ajax); + } try { $playlist->fastMakeCover($this->user->id, $_FILES["cover"]); - } catch(\Throwable $e) { - $this->flashFail("err", tr("error"), tr("invalid_cover_photo"), NULL, $is_ajax); + } catch (\Throwable $e) { + $this->flashFail("err", tr("error"), tr("invalid_cover_photo"), null, $is_ajax); } } $playlist->save(); - foreach($audios as $audio) { - $audio = $this->audios->get((int)$audio); - if(!$audio || $audio->isDeleted()) + foreach ($audios as $audio) { + $audio = $this->audios->get((int) $audio); + if (!$audio || $audio->isDeleted()) { continue; + } $playlist->add($audio); } - $playlist->bookmark(isset($club) ? $club : $this->user->identity); - if($is_ajax) { + $playlist->bookmark($club ?? $this->user->identity); + if ($is_ajax) { $this->returnJson([ 'success' => true, - 'redirect' => '/playlist' . $owner . "_" . $playlist->getId() + 'redirect' => '/playlist' . $owner . "_" . $playlist->getId(), ]); } $this->redirect("/playlist" . $owner . "_" . $playlist->getId()); @@ -394,7 +423,8 @@ final class AudioPresenter extends OpenVKPresenter } } - function renderPlaylistAction(int $id) { + public function renderPlaylistAction(int $id) + { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(true); $this->assertNoCSRF(); @@ -406,31 +436,35 @@ final class AudioPresenter extends OpenVKPresenter $playlist = $this->audios->getPlaylist($id); - if(!$playlist || $playlist->isDeleted()) + if (!$playlist || $playlist->isDeleted()) { $this->flashFail("err", "error", tr("invalid_playlist"), null, true); + } switch ($this->queryParam("act")) { case "bookmark": - if(!$playlist->isBookmarkedBy($this->user->identity)) + if (!$playlist->isBookmarkedBy($this->user->identity)) { $playlist->bookmark($this->user->identity); - else + } else { $this->flashFail("err", "error", tr("playlist_already_bookmarked"), null, true); + } break; case "unbookmark": - if($playlist->isBookmarkedBy($this->user->identity)) + if ($playlist->isBookmarkedBy($this->user->identity)) { $playlist->unbookmark($this->user->identity); - else + } else { $this->flashFail("err", "error", tr("playlist_not_bookmarked"), null, true); + } break; case "delete": - if($playlist->canBeModifiedBy($this->user->identity)) { + if ($playlist->canBeModifiedBy($this->user->identity)) { $tmOwner = $playlist->getOwner(); $playlist->delete(); - } else + } else { $this->flashFail("err", "error", tr("access_denied"), null, true); - + } + $this->returnJson(["success" => true, "id" => $tmOwner->getRealId()]); break; default: @@ -440,81 +474,87 @@ final class AudioPresenter extends OpenVKPresenter $this->returnJson(["success" => true]); } - function renderEditPlaylist(int $owner_id, int $virtual_id) + public function renderEditPlaylist(int $owner_id, int $virtual_id) { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); $playlist = $this->audios->getPlaylistByOwnerAndVID($owner_id, $virtual_id); - if (!$playlist || $playlist->isDeleted() || !$playlist->canBeModifiedBy($this->user->identity)) + if (!$playlist || $playlist->isDeleted() || !$playlist->canBeModifiedBy($this->user->identity)) { $this->notFound(); + } $this->template->playlist = $playlist; - + $audios = iterator_to_array($playlist->fetch(1, $playlist->size())); $this->template->audios = array_slice($audios, 0, 1000); $this->template->ownerId = $owner_id; $this->template->owner = $playlist->getOwner(); - if($_SERVER["REQUEST_METHOD"] !== "POST") + if ($_SERVER["REQUEST_METHOD"] !== "POST") { return; + } - $is_ajax = (int)$this->postParam('ajax') == 1; + $is_ajax = (int) $this->postParam('ajax') == 1; $title = $this->postParam("title"); $description = $this->postParam("description"); - $is_unlisted = (int)$this->postParam('is_unlisted'); + $is_unlisted = (int) $this->postParam('is_unlisted'); $new_audios = !empty($this->postParam("audios")) ? explode(",", rtrim($this->postParam("audios"), ",")) : []; - if(empty($title) || iconv_strlen($title) < 1) + if (empty($title) || iconv_strlen($title) < 1) { $this->flashFail("err", tr("error"), tr("set_playlist_name")); - + } + $playlist->setName(ovk_proc_strtr($title, 125)); $playlist->setDescription(ovk_proc_strtr($description, 2045)); $playlist->setEdited(time()); $playlist->resetLength(); - $playlist->setUnlisted((bool)$is_unlisted); + $playlist->setUnlisted((bool) $is_unlisted); - if($_FILES["cover"]["error"] === UPLOAD_ERR_OK) { - if(!str_starts_with($_FILES["cover"]["type"], "image")) + if ($_FILES["cover"]["error"] === UPLOAD_ERR_OK) { + if (!str_starts_with($_FILES["cover"]["type"], "image")) { $this->flashFail("err", tr("error"), tr("not_a_photo")); - + } + try { $playlist->fastMakeCover($this->user->id, $_FILES["cover"]); - } catch(\Throwable $e) { + } catch (\Throwable $e) { $this->flashFail("err", tr("error"), tr("invalid_cover_photo")); } } $playlist->save(); - + DatabaseConnection::i()->getContext()->table("playlist_relations")->where([ - "collection" => $playlist->getId() + "collection" => $playlist->getId(), ])->delete(); foreach ($new_audios as $new_audio) { - $audio = (new Audios)->get((int)$new_audio); - if(!$audio || $audio->isDeleted()) + $audio = (new Audios())->get((int) $new_audio); + if (!$audio || $audio->isDeleted()) { continue; + } $playlist->add($audio); } - if($is_ajax) { + if ($is_ajax) { $this->returnJson([ 'success' => true, - 'redirect' => '/playlist' . $playlist->getPrettyId() + 'redirect' => '/playlist' . $playlist->getPrettyId(), ]); } - $this->redirect("/playlist".$playlist->getPrettyId()); + $this->redirect("/playlist" . $playlist->getPrettyId()); } - function renderPlaylist(int $owner_id, int $virtual_id): void + public function renderPlaylist(int $owner_id, int $virtual_id): void { $this->assertUserLoggedIn(); $playlist = $this->audios->getPlaylistByOwnerAndVID($owner_id, $virtual_id); - $page = (int)($this->queryParam("p") ?? 1); - if (!$playlist || $playlist->isDeleted()) + $page = (int) ($this->queryParam("p") ?? 1); + if (!$playlist || $playlist->isDeleted()) { $this->notFound(); + } $this->template->playlist = $playlist; $this->template->page = $page; @@ -529,7 +569,7 @@ final class AudioPresenter extends OpenVKPresenter $this->template->count = $playlist->size(); } - function renderAction(int $audio_id): void + public function renderAction(int $audio_id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(true); @@ -542,60 +582,69 @@ final class AudioPresenter extends OpenVKPresenter $audio = $this->audios->get($audio_id); - if(!$audio || $audio->isDeleted()) + if (!$audio || $audio->isDeleted()) { $this->flashFail("err", "error", tr("invalid_audio"), null, true); + } switch ($this->queryParam("act")) { case "add": - if($audio->isWithdrawn()) + if ($audio->isWithdrawn()) { $this->flashFail("err", "error", tr("invalid_audio"), null, true); + } - if(!$audio->isInLibraryOf($this->user->identity)) + if (!$audio->isInLibraryOf($this->user->identity)) { $audio->add($this->user->identity); - else + } else { $this->flashFail("err", "error", tr("do_have_audio"), null, true); - + } + break; case "remove": - if($audio->isInLibraryOf($this->user->identity)) + if ($audio->isInLibraryOf($this->user->identity)) { $audio->remove($this->user->identity); - else + } else { $this->flashFail("err", "error", tr("do_not_have_audio"), null, true); + } break; case "remove_club": - $club = (new Clubs)->get((int)$this->postParam("club")); - - if(!$club || !$club->canBeModifiedBy($this->user->identity)) + $club = (new Clubs())->get((int) $this->postParam("club")); + + if (!$club || !$club->canBeModifiedBy($this->user->identity)) { $this->flashFail("err", "error", tr("access_denied"), null, true); - - if($audio->isInLibraryOf($club)) + } + + if ($audio->isInLibraryOf($club)) { $audio->remove($club); - else + } else { $this->flashFail("err", "error", tr("group_hasnt_audio"), null, true); + } break; case "add_to_club": $detailed = []; - if($audio->isWithdrawn()) + if ($audio->isWithdrawn()) { $this->flashFail("err", "error", tr("invalid_audio"), null, true); - - if(empty($this->postParam("clubs"))) + } + + if (empty($this->postParam("clubs"))) { $this->flashFail("err", "error", 'clubs not passed', null, true); - + } + $clubs_arr = explode(',', $this->postParam("clubs")); $count = sizeof($clubs_arr); - if($count < 1 || $count > 10) { + if ($count < 1 || $count > 10) { $this->flashFail("err", "error", tr('too_many_or_to_lack'), null, true); } - foreach($clubs_arr as $club_id) { - $club = (new Clubs)->get((int)$club_id); - if(!$club || !$club->canBeModifiedBy($this->user->identity)) + foreach ($clubs_arr as $club_id) { + $club = (new Clubs())->get((int) $club_id); + if (!$club || !$club->canBeModifiedBy($this->user->identity)) { continue; - - if(!$audio->isInLibraryOf($club)) { + } + + if (!$audio->isInLibraryOf($club)) { $detailed[$club_id] = true; $audio->add($club); } else { @@ -603,30 +652,33 @@ final class AudioPresenter extends OpenVKPresenter continue; } } - + $this->returnJson(["success" => true, 'detailed' => $detailed]); break; case "add_to_playlist": $detailed = []; - if($audio->isWithdrawn()) + if ($audio->isWithdrawn()) { $this->flashFail("err", "error", tr("invalid_audio"), null, true); - - if(empty($this->postParam("playlists"))) + } + + if (empty($this->postParam("playlists"))) { $this->flashFail("err", "error", 'playlists not passed', null, true); - + } + $playlists_arr = explode(',', $this->postParam("playlists")); $count = sizeof($playlists_arr); - if($count < 1 || $count > 10) { + if ($count < 1 || $count > 10) { $this->flashFail("err", "error", tr('too_many_or_to_lack'), null, true); } - foreach($playlists_arr as $playlist_id) { + foreach ($playlists_arr as $playlist_id) { $pid = explode('_', $playlist_id); - $playlist = (new Audios)->getPlaylistByOwnerAndVID((int)$pid[0], (int)$pid[1]); - if(!$playlist || !$playlist->canBeModifiedBy($this->user->identity)) + $playlist = (new Audios())->getPlaylistByOwnerAndVID((int) $pid[0], (int) $pid[1]); + if (!$playlist || !$playlist->canBeModifiedBy($this->user->identity)) { continue; - - if(!$playlist->hasAudio($audio)) { + } + + if (!$playlist->hasAudio($audio)) { $playlist->add($audio); $detailed[$playlist_id] = true; } else { @@ -638,32 +690,36 @@ final class AudioPresenter extends OpenVKPresenter $this->returnJson(["success" => true, 'detailed' => $detailed]); break; case "delete": - if($audio->canBeModifiedBy($this->user->identity)) + if ($audio->canBeModifiedBy($this->user->identity)) { $audio->delete(); - else + } else { $this->flashFail("err", "error", tr("access_denied"), null, true); + } break; case "edit": $audio = $this->audios->get($audio_id); - if (!$audio || $audio->isDeleted() || $audio->isWithdrawn()) + if (!$audio || $audio->isDeleted() || $audio->isWithdrawn()) { $this->flashFail("err", "error", tr("invalid_audio"), null, true); + } - if ($audio->getOwner()->getId() !== $this->user->id) + if ($audio->getOwner()->getId() !== $this->user->id) { $this->flashFail("err", "error", tr("access_denied"), null, true); + } $performer = $this->postParam("performer"); $name = $this->postParam("name"); $lyrics = $this->postParam("lyrics"); $genre = empty($this->postParam("genre")) ? "undefined" : $this->postParam("genre"); - $nsfw = (int)($this->postParam("explicit") ?? 0) === 1; - $unlisted = (int)($this->postParam("unlisted") ?? 0) === 1; - if(empty($performer) || empty($name) || iconv_strlen($performer . $name) > 128) # FQN of audio must not be more than 128 chars + $nsfw = (int) ($this->postParam("explicit") ?? 0) === 1; + $unlisted = (int) ($this->postParam("unlisted") ?? 0) === 1; + if (empty($performer) || empty($name) || iconv_strlen($performer . $name) > 128) { # FQN of audio must not be more than 128 chars $this->flashFail("err", tr("error"), tr("error_insufficient_info"), null, true); + } $audio->setName($name); $audio->setPerformer($performer); - $audio->setLyrics(empty($lyrics) ? NULL : $lyrics); + $audio->setLyrics(empty($lyrics) ? null : $lyrics); $audio->setGenre($genre); $audio->setExplicit($nsfw); $audio->setSearchability($unlisted); @@ -688,12 +744,12 @@ final class AudioPresenter extends OpenVKPresenter $this->returnJson(["success" => true]); } - function renderPlaylists(int $owner) + public function renderPlaylists(int $owner) { $this->renderList($owner, "playlists"); } - function renderApiGetContext() + public function renderApiGetContext() { if ($_SERVER["REQUEST_METHOD"] !== "POST") { header("HTTP/1.1 405 Method Not Allowed"); @@ -701,26 +757,28 @@ final class AudioPresenter extends OpenVKPresenter } $ctx_type = $this->postParam("context"); - $ctx_id = (int)($this->postParam("context_entity")); - $page = (int)($this->postParam("page") ?? 1); + $ctx_id = (int) ($this->postParam("context_entity")); + $page = (int) ($this->postParam("page") ?? 1); $perPage = 10; - switch($ctx_type) { + switch ($ctx_type) { default: case "entity_audios": - if($ctx_id >= 0) { - $entity = $ctx_id != 0 ? (new Users)->get($ctx_id) : $this->user->identity; + if ($ctx_id >= 0) { + $entity = $ctx_id != 0 ? (new Users())->get($ctx_id) : $this->user->identity; - if(!$entity || !$entity->getPrivacyPermission("audios.read", $this->user->identity)) + if (!$entity || !$entity->getPrivacyPermission("audios.read", $this->user->identity)) { $this->flashFail("err", "Error", "Can't get queue", 80, true); + } $audios = $this->audios->getByUser($entity, $page, $perPage); $audiosCount = $this->audios->getUserCollectionSize($entity); } else { - $entity = (new Clubs)->get(abs($ctx_id)); + $entity = (new Clubs())->get(abs($ctx_id)); - if(!$entity || $entity->isBanned()) + if (!$entity || $entity->isBanned()) { $this->flashFail("err", "Error", "Can't get queue", 80, true); + } $audios = $this->audios->getByClub($entity, $page, $perPage); $audiosCount = $this->audios->getClubCollectionSize($entity); @@ -737,8 +795,9 @@ final class AudioPresenter extends OpenVKPresenter case "playlist_context": $playlist = $this->audios->getPlaylist($ctx_id); - if (!$playlist || $playlist->isDeleted()) + if (!$playlist || $playlist->isDeleted()) { $this->flashFail("err", "Error", "Can't get queue", 80, true); + } $audios = $playlist->fetch($page, 10); $audiosCount = $playlist->size(); @@ -754,17 +813,20 @@ final class AudioPresenter extends OpenVKPresenter $params = []; $order = [ "type" => $data['order'] ?? 'id', - "invert" => (int)$data['invert'] == 1 ? true : false + "invert" => (int) $data['invert'] == 1 ? true : false, ]; - if($data['genre'] && $data['genre'] != 'any') + if ($data['genre'] && $data['genre'] != 'any') { $params['genre'] = $data['genre']; + } - if($data['only_performers'] && (int)$data['only_performers'] == 1) + if ($data['only_performers'] && (int) $data['only_performers'] == 1) { $params['only_performers'] = '1'; - - if($data['with_lyrics'] && (int)$data['with_lyrics'] == 1) + } + + if ($data['with_lyrics'] && (int) $data['with_lyrics'] == 1) { $params['with_lyrics'] = '1'; + } $stream = $this->audios->find($data['query'], $params, $order); $audios = $stream->page($page, 10); @@ -772,7 +834,7 @@ final class AudioPresenter extends OpenVKPresenter break; case 'alone_audio': $found_audio = $this->audios->get($ctx_id); - if(!$found_audio || $found_audio->isDeleted() || !$found_audio->canBeViewedBy($this->user->identity)) { + if (!$found_audio || $found_audio->isDeleted() || !$found_audio->canBeViewedBy($this->user->identity)) { $this->flashFail("err", "Error", "Not found", 89, true); } @@ -784,7 +846,7 @@ final class AudioPresenter extends OpenVKPresenter $pagesCount = ceil($audiosCount / $perPage); # костылёк для получения плееров в пикере аудиозаписей - if((int)($this->postParam("returnPlayers")) === 1) { + if ((int) ($this->postParam("returnPlayers")) === 1) { $this->template->audios = $audios; $this->template->page = $page; $this->template->pagesCount = $pagesCount; @@ -795,13 +857,13 @@ final class AudioPresenter extends OpenVKPresenter $audiosArr = []; - foreach($audios as $audio) { + foreach ($audios as $audio) { $output_array = []; $output_array['id'] = $audio->getId(); $output_array['name'] = $audio->getTitle(); $output_array['performer'] = $audio->getPerformer(); - if(!$audio->isWithdrawn()) { + if (!$audio->isWithdrawn()) { $output_array['keys'] = $audio->getKeys(); $output_array['url'] = $audio->getUrl(); } diff --git a/Web/Presenters/AuthPresenter.php b/Web/Presenters/AuthPresenter.php index 6db7758c..20d8775a 100644 --- a/Web/Presenters/AuthPresenter.php +++ b/Web/Presenters/AuthPresenter.php @@ -1,5 +1,9 @@ -authenticator = Authenticator::i(); $this->db = DatabaseConnection::i()->getContext(); - + $this->users = $users; $this->restores = $restores; $this->verifications = $verifications; - + parent::__construct(); } - + private function ipValid(): bool { - $ip = (new IPs)->get(CONNECTING_IP); + $ip = (new IPs())->get(CONNECTING_IP); $res = $ip->rateLimit(0); - + return $res === IP::RL_RESET || $res === IP::RL_CANEXEC; } - - function renderRegister(): void + + public function renderRegister(): void { - if(!is_null($this->user)) + if (!is_null($this->user)) { $this->redirect($this->user->identity->getURL()); - - if(!$this->hasPermission("user", "register", -1)) exit("Вас забанили"); - - $referer = NULL; - if(!is_null($refLink = $this->queryParam("ref"))) { + } + + if (!$this->hasPermission("user", "register", -1)) { + exit("Вас забанили"); + } + + $referer = null; + if (!is_null($refLink = $this->queryParam("ref"))) { $pieces = explode(" ", $refLink, 2); - if(sizeof($pieces) !== 2) + if (sizeof($pieces) !== 2) { $this->flashFail("err", tr("error"), tr("referral_link_invalid")); - + } + [$ref, $hash] = $pieces; $ref = hexdec($ref); $hash = base64_decode($hash); - - $referer = (new Users)->get($ref); - if(!$referer) + + $referer = (new Users())->get($ref); + if (!$referer) { $this->flashFail("err", tr("error"), tr("referral_link_invalid")); - - if($referer->getRefLinkId() !== $refLink) + } + + if ($referer->getRefLinkId() !== $refLink) { $this->flashFail("err", tr("error"), tr("referral_link_invalid")); + } } - + $this->template->referer = $referer; - - if($_SERVER["REQUEST_METHOD"] === "POST") { + + if ($_SERVER["REQUEST_METHOD"] === "POST") { $this->assertCaptchaCheckPassed(); - if(!OPENVK_ROOT_CONF['openvk']['preferences']['registration']['enable'] && !$referer) + if (!OPENVK_ROOT_CONF['openvk']['preferences']['registration']['enable'] && !$referer) { $this->flashFail("err", tr("failed_to_register"), tr("registration_disabled")); - - if(!$this->ipValid()) + } + + if (!$this->ipValid()) { $this->flashFail("err", tr("suspicious_registration_attempt"), tr("suspicious_registration_attempt_comment")); - - if(!Validator::i()->emailValid($this->postParam("email"))) + } + + if (!Validator::i()->emailValid($this->postParam("email"))) { $this->flashFail("err", tr("invalid_email_address"), tr("invalid_email_address_comment")); + } - if(OPENVK_ROOT_CONF['openvk']['preferences']['security']['forceStrongPassword']) - if(!Validator::i()->passwordStrong($this->postParam("password"))) + if (OPENVK_ROOT_CONF['openvk']['preferences']['security']['forceStrongPassword']) { + if (!Validator::i()->passwordStrong($this->postParam("password"))) { $this->flashFail("err", tr("error"), tr("error_weak_password")); + } + } - if (strtotime($this->postParam("birthday")) > time()) + if (strtotime($this->postParam("birthday")) > time()) { $this->flashFail("err", tr("invalid_birth_date"), tr("invalid_birth_date_comment")); + } - if (!$this->postParam("confirmation")) + if (!$this->postParam("confirmation")) { $this->flashFail("err", tr("error"), tr("checkbox_in_registration_unchecked")); + } try { - $user = new User; + $user = new User(); $user->setFirst_Name($this->postParam("first_name")); $user->setLast_Name($this->postParam("last_name")); switch ($this->postParam("pronouns")) { @@ -109,120 +126,130 @@ final class AuthPresenter extends OpenVKPresenter $user->setEmail($this->postParam("email")); $user->setSince(date("Y-m-d H:i:s")); $user->setRegistering_Ip(CONNECTING_IP); - $user->setBirthday(empty($this->postParam("birthday")) ? NULL : strtotime($this->postParam("birthday"))); - $user->setActivated((int)!OPENVK_ROOT_CONF['openvk']['preferences']['security']['requireEmail']); - } catch(InvalidUserNameException $ex) { + $user->setBirthday(empty($this->postParam("birthday")) ? null : strtotime($this->postParam("birthday"))); + $user->setActivated((int) !OPENVK_ROOT_CONF['openvk']['preferences']['security']['requireEmail']); + } catch (InvalidUserNameException $ex) { $this->flashFail("err", tr("error"), tr("invalid_real_name")); } $chUser = ChandlerUser::create($this->postParam("email"), $this->postParam("password")); - if(!$chUser) + if (!$chUser) { $this->flashFail("err", tr("failed_to_register"), tr("user_already_exists")); + } $user->setUser($chUser->getId()); $user->save(false); - - if(!is_null($referer)) { + + if (!is_null($referer)) { $user->toggleSubscription($referer); $referer->toggleSubscription($user); } if (OPENVK_ROOT_CONF['openvk']['preferences']['security']['requireEmail']) { - $verification = new EmailVerification; + $verification = new EmailVerification(); $verification->setProfile($user->getId()); $verification->save(); - + $params = [ "key" => $verification->getKey(), "name" => $user->getCanonicalName(), ]; $this->sendmail($user->getEmail(), "verify-email", $params); #Vulnerability possible } - + $this->authenticator->authenticate($chUser->getId()); $this->redirect("/id" . $user->getId()); $user->save(); } } - - function renderLogin(): void + + public function renderLogin(): void { $redirUrl = $this->requestParam("jReturnTo"); - - if(!is_null($this->user)) + + if (!is_null($this->user)) { $this->redirect($redirUrl ?? $this->user->identity->getURL()); - - if(!$this->hasPermission("user", "login", -1)) exit("Вас забанили"); - - if($_SERVER["REQUEST_METHOD"] === "POST") { + } + + if (!$this->hasPermission("user", "login", -1)) { + exit("Вас забанили"); + } + + if ($_SERVER["REQUEST_METHOD"] === "POST") { $user = $this->db->table("ChandlerUsers")->where("login", $this->postParam("login"))->fetch(); - if(!$user) + if (!$user) { $this->flashFail("err", tr("login_failed"), tr("invalid_username_or_password")); - - if(!$this->authenticator->verifyCredentials($user->id, $this->postParam("password"))) + } + + if (!$this->authenticator->verifyCredentials($user->id, $this->postParam("password"))) { $this->flashFail("err", tr("login_failed"), tr("invalid_username_or_password")); + } $ovkUser = new User($user->related("profiles.user")->fetch()); - if($ovkUser->isDeleted() && !$ovkUser->isDeactivated()) + if ($ovkUser->isDeleted() && !$ovkUser->isDeactivated()) { $this->flashFail("err", tr("login_failed"), tr("invalid_username_or_password")); + } $secret = $user->related("profiles.user")->fetch()["2fa_secret"]; $code = $this->postParam("code"); - if(!is_null($secret)) { + if (!is_null($secret)) { $this->template->_template = "Auth/LoginSecondFactor.xml"; $this->template->login = $this->postParam("login"); $this->template->password = $this->postParam("password"); - if(is_null($code)) + if (is_null($code)) { return; + } - if(!($code === (new Totp)->GenerateToken(Base32::decode($secret)) || $ovkUser->use2faBackupCode((int) $code))) { + if (!($code === (new Totp())->GenerateToken(Base32::decode($secret)) || $ovkUser->use2faBackupCode((int) $code))) { $this->flash("err", tr("login_failed"), tr("incorrect_2fa_code")); return; } } - + $this->authenticator->authenticate($user->id); $this->redirect($redirUrl ?? $ovkUser->getURL()); } } - - function renderSu(string $uuid): void + + public function renderSu(string $uuid): void { $this->assertNoCSRF(); $this->assertUserLoggedIn(); - - if($uuid === "unset") { - Session::i()->set("_su", NULL); + + if ($uuid === "unset") { + Session::i()->set("_su", null); $this->redirect("/"); } - - if(!$this->db->table("ChandlerUsers")->where("id", $uuid)) + + if (!$this->db->table("ChandlerUsers")->where("id", $uuid)) { $this->flashFail("err", tr("token_manipulation_error"), tr("profile_not_found")); - + } + $this->assertPermission('openvk\Web\Models\Entities\User', 'substitute', 0); Session::i()->set("_su", $uuid); $this->flash("succ", tr("profile_changed"), tr("profile_changed_comment")); $this->redirect("/"); } - - function renderLogout(): void + + public function renderLogout(): void { $this->assertUserLoggedIn(); $this->assertNoCSRF(); $this->authenticator->logout(); - Session::i()->set("_su", NULL); - + Session::i()->set("_su", null); + $this->redirect("/"); } - - function renderFinishRestoringPassword(): void + + public function renderFinishRestoringPassword(): void { - if(OPENVK_ROOT_CONF['openvk']['preferences']['security']['disablePasswordRestoring']) + if (OPENVK_ROOT_CONF['openvk']['preferences']['security']['disablePasswordRestoring']) { $this->notFound(); + } $request = $this->restores->getByToken(str_replace(" ", "+", $this->queryParam("key"))); - if(!$request || !$request->isStillValid()) { + if (!$request || !$request->isStillValid()) { $this->flash("err", tr("token_manipulation_error"), tr("token_manipulation_error_comment")); $this->redirect("/"); return; @@ -230,13 +257,13 @@ final class AuthPresenter extends OpenVKPresenter $this->template->disable_ajax = 1; $this->template->is2faEnabled = $request->getUser()->is2faEnabled(); - - if($_SERVER["REQUEST_METHOD"] === "POST") { - if($request->getUser()->is2faEnabled()) { + + if ($_SERVER["REQUEST_METHOD"] === "POST") { + if ($request->getUser()->is2faEnabled()) { $user = $request->getUser(); $code = $this->postParam("code"); $secret = $user->get2faSecret(); - if(!($code === (new Totp)->GenerateToken(Base32::decode($secret)) || $user->use2faBackupCode((int) $code))) { + if (!($code === (new Totp())->GenerateToken(Base32::decode($secret)) || $user->use2faBackupCode((int) $code))) { $this->flash("err", tr("error"), tr("incorrect_2fa_code")); return; } @@ -244,88 +271,96 @@ final class AuthPresenter extends OpenVKPresenter $user = $request->getUser()->getChandlerUser(); $this->db->table("ChandlerTokens")->where("user", $user->getId())->delete(); #Logout from everywhere - + $user->updatePassword($this->postParam("password")); $this->authenticator->authenticate($user->getId()); - + $request->delete(false); $this->flash("succ", tr("information_-1"), tr("password_successfully_reset")); $this->redirect("/settings"); } } - - function renderRestore(): void + + public function renderRestore(): void { - if(OPENVK_ROOT_CONF['openvk']['preferences']['security']['disablePasswordRestoring']) + if (OPENVK_ROOT_CONF['openvk']['preferences']['security']['disablePasswordRestoring']) { $this->notFound(); + } - if(!is_null($this->user)) + if (!is_null($this->user)) { $this->redirect($this->user->identity->getURL()); + } - if(($this->queryParam("act") ?? "default") === "finish") + if (($this->queryParam("act") ?? "default") === "finish") { $this->pass("openvk!Auth->finishRestoringPassword"); - - if($_SERVER["REQUEST_METHOD"] === "POST") { + } + + if ($_SERVER["REQUEST_METHOD"] === "POST") { $uRow = $this->db->table("ChandlerUsers")->where("login", $this->postParam("login"))->fetch(); - if(!$uRow) { + if (!$uRow) { #Privacy of users must be protected. We will not tell if email is bound to a user or not. $this->flashFail("succ", tr("information_-1"), tr("password_reset_email_sent")); } - + $user = $this->users->getByChandlerUser(new ChandlerUser($uRow)); - if(!$user || $user->isDeleted()) + if (!$user || $user->isDeleted()) { $this->flashFail("err", tr("error"), tr("password_reset_error")); - + } + $request = $this->restores->getLatestByUser($user); - if(!is_null($request) && $request->isNew()) + if (!is_null($request) && $request->isNew()) { $this->flashFail("err", tr("forbidden"), tr("password_reset_rate_limit_error")); - - $resetObj = new PasswordReset; + } + + $resetObj = new PasswordReset(); $resetObj->setProfile($user->getId()); $resetObj->save(); - + $params = [ "key" => $resetObj->getKey(), "name" => $user->getCanonicalName(), ]; $this->sendmail($uRow->login, "password-reset", $params); #Vulnerability possible - + $this->flashFail("succ", tr("information_-1"), tr("password_reset_email_sent")); } } - function renderResendEmail(): void + public function renderResendEmail(): void { - if(!is_null($this->user) && $this->user->identity->isActivated()) + if (!is_null($this->user) && $this->user->identity->isActivated()) { $this->redirect($this->user->identity->getURL()); + } - if($_SERVER["REQUEST_METHOD"] === "POST") { + if ($_SERVER["REQUEST_METHOD"] === "POST") { $user = $this->user->identity; - if(!$user || $user->isDeleted() || $user->isActivated()) + if (!$user || $user->isDeleted() || $user->isActivated()) { $this->flashFail("err", tr("error"), tr("email_error")); - + } + $request = $this->verifications->getLatestByUser($user); - if(!is_null($request) && $request->isNew()) + if (!is_null($request) && $request->isNew()) { $this->flashFail("err", tr("forbidden"), tr("email_rate_limit_error")); - - $verification = new EmailVerification; + } + + $verification = new EmailVerification(); $verification->setProfile($user->getId()); $verification->save(); - + $params = [ "key" => $verification->getKey(), "name" => $user->getCanonicalName(), ]; $this->sendmail($user->getEmail(), "verify-email", $params); #Vulnerability possible - + $this->flashFail("succ", tr("information_-1"), tr("email_sent")); } } - function renderVerifyEmail(): void + public function renderVerifyEmail(): void { $request = $this->verifications->getByToken(str_replace(" ", "+", $this->queryParam("key"))); - if(!$request || !$request->isStillValid()) { + if (!$request || !$request->isStillValid()) { $this->flash("err", tr("token_manipulation_error"), tr("token_manipulation_error_comment")); $this->redirect("/"); } else { @@ -338,7 +373,7 @@ final class AuthPresenter extends OpenVKPresenter } } - function renderReactivatePage(): void + public function renderReactivatePage(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); @@ -348,36 +383,38 @@ final class AuthPresenter extends OpenVKPresenter $this->redirect("/"); } - function renderUnbanThemself(): void + public function renderUnbanThemself(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - if(!$this->user->identity->canUnbanThemself()) + if (!$this->user->identity->canUnbanThemself()) { $this->flashFail("err", tr("error"), tr("forbidden")); + } $user = $this->users->get($this->user->id); - $ban = (new Bans)->get((int)$user->getRawBanReason()); - if (!$ban || $ban->isOver() || $ban->isPermanent()) + $ban = (new Bans())->get((int) $user->getRawBanReason()); + if (!$ban || $ban->isOver() || $ban->isPermanent()) { $this->flashFail("err", tr("error"), tr("forbidden")); + } $ban->setRemoved_Manually(2); $ban->setRemoved_By($this->user->identity->getId()); $ban->save(); - $user->setBlock_Reason(NULL); + $user->setBlock_Reason(null); // $user->setUnblock_Time(NULL); $user->save(); $this->flashFail("succ", tr("banned_unban_title"), tr("banned_unban_description")); } - + /* * This function will revoke all tokens, including API and Web tokens and except active one - * + * * OF COURSE it requires CSRF - */ - function renderRevokeAllTokens(): void + */ + public function renderRevokeAllTokens(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); @@ -389,4 +426,4 @@ final class AuthPresenter extends OpenVKPresenter $this->db->table("ChandlerTokens")->where("user", $this->user->identity->getChandlerGUID())->where("token != ?", Session::i()->get("tok"))->delete(); $this->flashFail("succ", tr("information_-1"), tr("end_all_sessions_done")); } -} +} diff --git a/Web/Presenters/AwayPresenter.php b/Web/Presenters/AwayPresenter.php index 18c7cca7..08025100 100644 --- a/Web/Presenters/AwayPresenter.php +++ b/Web/Presenters/AwayPresenter.php @@ -1,16 +1,22 @@ -check($this->queryParam("to") . "/"); - if (OPENVK_ROOT_CONF["openvk"]["preferences"]["susLinks"]["warnings"]) - if (sizeof($checkBanEntries) > 0) + $checkBanEntries = (new BannedLinks())->check($this->queryParam("to") . "/"); + if (OPENVK_ROOT_CONF["openvk"]["preferences"]["susLinks"]["warnings"]) { + if (sizeof($checkBanEntries) > 0) { $this->pass("openvk!Away->view", $checkBanEntries[0]); + } + } header("HTTP/1.0 302 Found"); header("X-Robots-Tag: noindex, nofollow, noarchive"); @@ -18,11 +24,13 @@ final class AwayPresenter extends OpenVKPresenter exit; } - function renderView(int $lid) { - $this->template->link = (new BannedLinks)->get($lid); + public function renderView(int $lid) + { + $this->template->link = (new BannedLinks())->get($lid); - if (!$this->template->link) + if (!$this->template->link) { $this->notFound(); + } $this->template->to = $this->queryParam("to"); } diff --git a/Web/Presenters/BannedLinkPresenter.php b/Web/Presenters/BannedLinkPresenter.php index 6a11b3fc..3544dd82 100644 --- a/Web/Presenters/BannedLinkPresenter.php +++ b/Web/Presenters/BannedLinkPresenter.php @@ -1,4 +1,7 @@ -template->link = (new BannedLinks)->get($lid); + public function renderView(int $lid) + { + $this->template->link = (new BannedLinks())->get($lid); $this->template->to = $this->queryParam("to"); } } diff --git a/Web/Presenters/BlobPresenter.php b/Web/Presenters/BlobPresenter.php index 5987281d..99b57816 100644 --- a/Web/Presenters/BlobPresenter.php +++ b/Web/Presenters/BlobPresenter.php @@ -1,4 +1,7 @@ -getDirName($dir); $base = realpath(OPENVK_ROOT . "/storage/$dir"); $path = realpath(OPENVK_ROOT . "/storage/$dir/$name.$format"); - if(!$path) # Will also check if file exists since realpath fails on ENOENT + if (!$path) { # Will also check if file exists since realpath fails on ENOENT $this->notFound(); - else if(strpos($path, $path) !== 0) # Prevent directory traversal and storage container escape + } elseif (strpos($path, $path) !== 0) { # Prevent directory traversal and storage container escape $this->notFound(); - - if(isset($_SERVER["HTTP_IF_NONE_MATCH"])) + } + + if (isset($_SERVER["HTTP_IF_NONE_MATCH"])) { exit(header("HTTP/1.1 304 Not Modified")); - + } + header("Content-Type: " . mime_content_type($path)); header("Content-Size: " . filesize($path)); header("Cache-Control: public, max-age=1210000"); header("X-Accel-Expires: 1210000"); header("ETag: W/\"" . hash_file("snefru", $path) . "\""); - + readfile($path); exit; - } + } } diff --git a/Web/Presenters/CommentPresenter.php b/Web/Presenters/CommentPresenter.php index 76279ad6..0353acf8 100644 --- a/Web/Presenters/CommentPresenter.php +++ b/Web/Presenters/CommentPresenter.php @@ -1,5 +1,9 @@ - "openvk\\Web\\Models\\Repositories\\Notes", "topics" => "openvk\\Web\\Models\\Repositories\\Topics", ]; - - function renderLike(int $id): void + + public function renderLike(int $id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - - $comment = (new Comments)->get($id); - if(!$comment || $comment->isDeleted()) $this->notFound(); - if ($comment->getTarget() instanceof Post && $comment->getTarget()->getWallOwner()->isBanned()) + $comment = (new Comments())->get($id); + if (!$comment || $comment->isDeleted()) { + $this->notFound(); + } + + if ($comment->getTarget() instanceof Post && $comment->getTarget()->getWallOwner()->isBanned()) { $this->flashFail("err", tr("error"), tr("forbidden")); - - if(!is_null($this->user)) $comment->toggleLike($this->user->identity); - if($_SERVER["REQUEST_METHOD"] === "POST") { + } + + if (!is_null($this->user)) { + $comment->toggleLike($this->user->identity); + } + if ($_SERVER["REQUEST_METHOD"] === "POST") { $this->returnJson([ 'success' => true, ]); @@ -35,68 +44,77 @@ final class CommentPresenter extends OpenVKPresenter $this->redirect($_SERVER["HTTP_REFERER"]); } - - function renderMakeComment(string $repo, int $eId): void + + public function renderMakeComment(string $repo, int $eId): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - - $repoClass = $this->models[$repo] ?? NULL; - if(!$repoClass) chandler_http_panic(400, "Bad Request", "Unexpected $repo."); - - $repo = new $repoClass; - $entity = $repo->get($eId); - if(!$entity) $this->notFound(); - if(!$entity->canBeViewedBy($this->user->identity)) { + $repoClass = $this->models[$repo] ?? null; + if (!$repoClass) { + chandler_http_panic(400, "Bad Request", "Unexpected $repo."); + } + + $repo = new $repoClass(); + $entity = $repo->get($eId); + if (!$entity) { + $this->notFound(); + } + + if (!$entity->canBeViewedBy($this->user->identity)) { $this->flashFail("err", tr("error"), tr("forbidden")); } - if($entity instanceof Topic && $entity->isClosed()) + if ($entity instanceof Topic && $entity->isClosed()) { $this->notFound(); + } - if($entity instanceof Post && $entity->getTargetWall() < 0) - $club = (new Clubs)->get(abs($entity->getTargetWall())); - else if($entity instanceof Topic) + if ($entity instanceof Post && $entity->getTargetWall() < 0) { + $club = (new Clubs())->get(abs($entity->getTargetWall())); + } elseif ($entity instanceof Topic) { $club = $entity->getClub(); + } - if ($entity instanceof Post && $entity->getWallOwner()->isBanned()) + if ($entity instanceof Post && $entity->getWallOwner()->isBanned()) { $this->flashFail("err", tr("error"), tr("forbidden")); + } $flags = 0; - if($this->postParam("as_group") === "on" && !is_null($club) && $club->canBeModifiedBy($this->user->identity)) + if ($this->postParam("as_group") === "on" && !is_null($club) && $club->canBeModifiedBy($this->user->identity)) { $flags |= 0b10000000; + } - $photo = NULL; - if($_FILES["_pic_attachment"]["error"] === UPLOAD_ERR_OK) { + $photo = null; + if ($_FILES["_pic_attachment"]["error"] === UPLOAD_ERR_OK) { try { $photo = Photo::fastMake($this->user->id, $this->postParam("text"), $_FILES["_pic_attachment"]); - } catch(ISE $ex) { + } catch (ISE $ex) { $this->flashFail("err", tr("error_when_publishing_comment"), tr("error_when_publishing_comment_description")); } } $horizontal_attachments = []; $vertical_attachments = []; - if(!empty($this->postParam("horizontal_attachments"))) { + if (!empty($this->postParam("horizontal_attachments"))) { $horizontal_attachments_array = array_slice(explode(",", $this->postParam("horizontal_attachments")), 0, OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["maxAttachments"]); - if(sizeof($horizontal_attachments_array) > 0) { + if (sizeof($horizontal_attachments_array) > 0) { $horizontal_attachments = parseAttachments($horizontal_attachments_array, ['photo', 'video']); } } - if(!empty($this->postParam("vertical_attachments"))) { + if (!empty($this->postParam("vertical_attachments"))) { $vertical_attachments_array = array_slice(explode(",", $this->postParam("vertical_attachments")), 0, OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["maxAttachments"]); - if(sizeof($vertical_attachments_array) > 0) { + if (sizeof($vertical_attachments_array) > 0) { $vertical_attachments = parseAttachments($vertical_attachments_array, ['audio', 'note', 'doc']); } } - - if(empty($this->postParam("text")) && sizeof($horizontal_attachments) < 1 && sizeof($vertical_attachments) < 1) + + if (empty($this->postParam("text")) && sizeof($horizontal_attachments) < 1 && sizeof($vertical_attachments) < 1) { $this->flashFail("err", tr("error_when_publishing_comment"), tr("error_comment_empty")); - + } + try { - $comment = new Comment; + $comment = new Comment(); $comment->setOwner($this->user->id); $comment->setModel(get_class($entity)); $comment->setTarget($entity->getId()); @@ -107,50 +125,59 @@ final class CommentPresenter extends OpenVKPresenter } catch (\LengthException $ex) { $this->flashFail("err", tr("error_when_publishing_comment"), tr("error_comment_too_big")); } - - foreach($horizontal_attachments as $horizontal_attachment) { - if(!$horizontal_attachment || $horizontal_attachment->isDeleted() || !$horizontal_attachment->canBeViewedBy($this->user->identity)) { + + foreach ($horizontal_attachments as $horizontal_attachment) { + if (!$horizontal_attachment || $horizontal_attachment->isDeleted() || !$horizontal_attachment->canBeViewedBy($this->user->identity)) { continue; } $comment->attach($horizontal_attachment); } - foreach($vertical_attachments as $vertical_attachment) { - if(!$vertical_attachment || $vertical_attachment->isDeleted() || !$vertical_attachment->canBeViewedBy($this->user->identity)) { + foreach ($vertical_attachments as $vertical_attachment) { + if (!$vertical_attachment || $vertical_attachment->isDeleted() || !$vertical_attachment->canBeViewedBy($this->user->identity)) { continue; } $comment->attach($vertical_attachment); } - - if($entity->getOwner()->getId() !== $this->user->identity->getId()) - if(($owner = $entity->getOwner()) instanceof User) + + if ($entity->getOwner()->getId() !== $this->user->identity->getId()) { + if (($owner = $entity->getOwner()) instanceof User) { (new CommentNotification($owner, $comment, $entity, $this->user->identity))->emit(); - + } + } + $excludeMentions = [$this->user->identity->getId()]; - if(($owner = $entity->getOwner()) instanceof User) + if (($owner = $entity->getOwner()) instanceof User) { $excludeMentions[] = $owner->getId(); + } $mentions = iterator_to_array($comment->resolveMentions($excludeMentions)); - foreach($mentions as $mentionee) - if($mentionee instanceof User) + foreach ($mentions as $mentionee) { + if ($mentionee instanceof User) { (new MentionNotification($mentionee, $entity, $comment->getOwner(), strip_tags($comment->getText())))->emit(); - + } + } + $this->flashFail("succ", tr("comment_is_added"), tr("comment_is_added_desc")); } - - function renderDeleteComment(int $id): void + + public function renderDeleteComment(int $id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - - $comment = (new Comments)->get($id); - if(!$comment) $this->notFound(); - if(!$comment->canBeDeletedBy($this->user->identity)) + + $comment = (new Comments())->get($id); + if (!$comment) { + $this->notFound(); + } + if (!$comment->canBeDeletedBy($this->user->identity)) { $this->throwError(403, "Forbidden", tr("error_access_denied")); - if ($comment->getTarget() instanceof Post && $comment->getTarget()->getWallOwner()->isBanned()) + } + if ($comment->getTarget() instanceof Post && $comment->getTarget()->getWallOwner()->isBanned()) { $this->flashFail("err", tr("error"), tr("forbidden")); + } $comment->delete(); $this->flashFail( diff --git a/Web/Presenters/ContentSearchPresenter.php b/Web/Presenters/ContentSearchPresenter.php index f0898fe3..6fadd687 100644 --- a/Web/Presenters/ContentSearchPresenter.php +++ b/Web/Presenters/ContentSearchPresenter.php @@ -1,20 +1,23 @@ -repo = $repo; } - - function renderIndex(): void + + public function renderIndex(): void { - if($_SERVER["REQUEST_METHOD"] === "POST") - { + if ($_SERVER["REQUEST_METHOD"] === "POST") { $this->template->results = $repo->find([ "query" => $this->postParam("query"), ]); diff --git a/Web/Presenters/DocumentsPresenter.php b/Web/Presenters/DocumentsPresenter.php index 92521e20..b003b932 100644 --- a/Web/Presenters/DocumentsPresenter.php +++ b/Web/Presenters/DocumentsPresenter.php @@ -1,5 +1,9 @@ -assertUserLoggedIn(); $this->template->_template = "Documents/List.xml"; - if($owner_id > 0) + if ($owner_id > 0) { $this->notFound(); - - if($owner_id < 0) { - $owner = (new Clubs)->get(abs($owner_id)); - if(!$owner || $owner->isBanned()) - $this->notFound(); - else - $this->template->group = $owner; } - if(!$owner_id) - $owner_id = $this->user->id; + if ($owner_id < 0) { + $owner = (new Clubs())->get(abs($owner_id)); + if (!$owner || $owner->isBanned()) { + $this->notFound(); + } else { + $this->template->group = $owner; + } + } - $current_tab = (int)($this->queryParam("tab") ?? 0); - $current_order = (int)($this->queryParam("order") ?? 0); - $page = (int)($this->queryParam("p") ?? 1); + if (!$owner_id) { + $owner_id = $this->user->id; + } + + $current_tab = (int) ($this->queryParam("tab") ?? 0); + $current_order = (int) ($this->queryParam("order") ?? 0); + $page = (int) ($this->queryParam("p") ?? 1); $order = in_array($current_order, [0,1,2]) ? $current_order : 0; $tab = in_array($current_tab, [0,1,2,3,4,5,6,7,8]) ? $current_tab : 0; $api_request = $this->queryParam("picker") == "1"; - if($api_request && $_SERVER["REQUEST_METHOD"] === "POST") { + if ($api_request && $_SERVER["REQUEST_METHOD"] === "POST") { $ctx_type = $this->postParam("context"); - $docs = NULL; + $docs = null; - switch($ctx_type) { + switch ($ctx_type) { default: case "list": - $docs = (new Documents)->getDocumentsByOwner($owner_id, (int)$order, (int)$tab); + $docs = (new Documents())->getDocumentsByOwner($owner_id, (int) $order, (int) $tab); break; case "search": $ctx_query = $this->postParam("ctx_query"); - $docs = (new Documents)->find($ctx_query); + $docs = (new Documents())->find($ctx_query); break; } @@ -58,17 +65,17 @@ final class DocumentsPresenter extends OpenVKPresenter return; } - $docs = (new Documents)->getDocumentsByOwner($owner_id, (int)$order, (int)$tab); - $this->template->tabs = (new Documents)->getTypes($owner_id); - $this->template->tags = (new Documents)->getTags($owner_id, (int)$tab); + $docs = (new Documents())->getDocumentsByOwner($owner_id, (int) $order, (int) $tab); + $this->template->tabs = (new Documents())->getTypes($owner_id); + $this->template->tags = (new Documents())->getTags($owner_id, (int) $tab); $this->template->current_tab = $tab; $this->template->order = $order; $this->template->count = $docs->size(); $this->template->docs = iterator_to_array($docs->page($page, OPENVK_DEFAULT_PER_PAGE)); $this->template->locale_string = "you_have_x_documents"; - if($owner_id < 0) { + if ($owner_id < 0) { $this->template->locale_string = "group_has_x_documents"; - } elseif($current_tab != 0) { + } elseif ($current_tab != 0) { $this->template->locale_string = "x_documents_in_tab"; } @@ -81,39 +88,42 @@ final class DocumentsPresenter extends OpenVKPresenter ]; } - function renderListGroup(?int $gid) + public function renderListGroup(?int $gid) { $this->renderList($gid); } - function renderUpload() + public function renderUpload() { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - $group = NULL; + $group = null; $isAjax = $this->postParam("ajax", false) == 1; $ref = $this->postParam("referrer", false) ?? "user"; - if(!is_null($this->queryParam("gid"))) { + if (!is_null($this->queryParam("gid"))) { $gid = (int) $this->queryParam("gid"); - $group = (new Clubs)->get($gid); - if(!$group || $group->isBanned()) + $group = (new Clubs())->get($gid); + if (!$group || $group->isBanned()) { $this->flashFail("err", tr("forbidden"), tr("not_enough_permissions_comment"), null, $isAjax); + } - if(!$group->canUploadDocs($this->user->identity)) + if (!$group->canUploadDocs($this->user->identity)) { $this->flashFail("err", tr("forbidden"), tr("not_enough_permissions_comment"), null, $isAjax); + } } $this->template->group = $group; - if($_SERVER["REQUEST_METHOD"] !== "POST") + if ($_SERVER["REQUEST_METHOD"] !== "POST") { return; + } $owner = $this->user->id; - if($group) { + if ($group) { $owner = $group->getRealId(); } - + $upload = $_FILES["blob"]; $name = $this->postParam("name"); $tags = $this->postParam("tags"); @@ -121,11 +131,11 @@ final class DocumentsPresenter extends OpenVKPresenter $owner_hidden = ($this->postParam("owner_hidden") ?? "off") === "on"; try { - $document = new Document; + $document = new Document(); $document->setOwner($owner); $document->setName(ovk_proc_strtr($name, 255)); $document->setFolder_id($folder); - $document->setTags(empty($tags) ? NULL : $tags); + $document->setTags(empty($tags) ? null : $tags); $document->setOwner_hidden($owner_hidden); $document->setFile([ "tmp_name" => $upload["tmp_name"], @@ -134,19 +144,19 @@ final class DocumentsPresenter extends OpenVKPresenter "size" => $upload["size"], "preview_owner" => $this->user->id, ]); - + $document->save(); - } catch(\TypeError $e) { + } catch (\TypeError $e) { $this->flashFail("err", tr("forbidden"), $e->getMessage(), null, $isAjax); - } catch(ISE $e) { + } catch (ISE $e) { $this->flashFail("err", tr("forbidden"), "corrupted file", null, $isAjax); - } catch(\ValueError $e) { + } catch (\ValueError $e) { $this->flashFail("err", tr("forbidden"), $e->getMessage(), null, $isAjax); - } catch(\ImagickException $e) { + } catch (\ImagickException $e) { $this->flashFail("err", tr("forbidden"), tr("error_file_preview"), null, $isAjax); } - if(!$isAjax) { + if (!$isAjax) { $this->redirect("/docs" . (isset($group) ? $group->getRealId() : "")); } else { $this->returnJson([ @@ -156,17 +166,19 @@ final class DocumentsPresenter extends OpenVKPresenter } } - function renderPage(int $virtual_id, int $real_id): void + public function renderPage(int $virtual_id, int $real_id): void { $this->assertUserLoggedIn(); $access_key = $this->queryParam("key"); - $doc = (new Documents)->getDocumentById((int)$virtual_id, (int)$real_id, $access_key); - if(!$doc || $doc->isDeleted()) + $doc = (new Documents())->getDocumentById((int) $virtual_id, (int) $real_id, $access_key); + if (!$doc || $doc->isDeleted()) { $this->notFound(); - - if(!$doc->checkAccessKey($access_key)) + } + + if (!$doc->checkAccessKey($access_key)) { $this->notFound(); + } $this->template->doc = $doc; $this->template->type = $doc->getVKAPIType(); diff --git a/Web/Presenters/GiftsPresenter.php b/Web/Presenters/GiftsPresenter.php index 6e85a29d..007be976 100644 --- a/Web/Presenters/GiftsPresenter.php +++ b/Web/Presenters/GiftsPresenter.php @@ -1,5 +1,9 @@ -gifts = $gifts; $this->users = $users; } - - function renderUserGifts(int $user): void + + public function renderUserGifts(int $user): void { $this->assertUserLoggedIn(); - + $user = $this->users->get($user); - if(!$user || $user->isDeleted()) + if (!$user || $user->isDeleted()) { $this->notFound(); - - if(!$user->canBeViewedBy($this->user->identity ?? NULL)) + } + + if (!$user->canBeViewedBy($this->user->identity ?? null)) { $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); + } $this->template->user = $user; $this->template->page = $page = (int) ($this->queryParam("p") ?? 1); @@ -32,120 +38,129 @@ final class GiftsPresenter extends OpenVKPresenter $this->template->iterator = $user->getGifts($page); $this->template->hideInfo = $this->user->id !== $user->getId(); } - - function renderGiftMenu(): void + + public function renderGiftMenu(): void { $user = $this->users->get((int) ($this->queryParam("user") ?? 0)); - if(!$user) + if (!$user) { $this->notFound(); - + } + $this->template->page = $page = (int) ($this->queryParam("p") ?? 1); - $cats = $this->gifts->getCategories($page, NULL, $this->template->count); - + $cats = $this->gifts->getCategories($page, null, $this->template->count); + $this->template->user = $user; $this->template->iterator = $cats; $this->template->count = $this->gifts->getCategoriesCount(); $this->template->_template = "Gifts/Menu.xml"; } - - function renderGiftList(): void + + public function renderGiftList(): void { $user = $this->users->get((int) ($this->queryParam("user") ?? 0)); $cat = $this->gifts->getCat((int) ($this->queryParam("pack") ?? 0)); - if(!$user || !$cat) + if (!$user || !$cat) { $this->flashFail("err", tr("error_when_gifting"), tr("error_user_not_exists")); - - if(!$user->canBeViewedBy($this->user->identity)) + } + + if (!$user->canBeViewedBy($this->user->identity)) { $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); - + } + $this->template->page = $page = (int) ($this->queryParam("p") ?? 1); $gifts = $cat->getGifts($page, null, $this->template->count); - + $this->template->user = $user; $this->template->cat = $cat; $this->template->gifts = iterator_to_array($gifts); $this->template->_template = "Gifts/Pick.xml"; } - - function renderConfirmGift(): void + + public function renderConfirmGift(): void { $user = $this->users->get((int) ($this->queryParam("user") ?? 0)); $gift = $this->gifts->get((int) ($this->queryParam("elid") ?? 0)); $cat = $this->gifts->getCat((int) ($this->queryParam("pack") ?? 0)); - if(!$user || !$cat || !$gift || !$cat->hasGift($gift)) + if (!$user || !$cat || !$gift || !$cat->hasGift($gift)) { $this->flashFail("err", tr("error_when_gifting"), tr("error_no_rights_gifts")); - - if(!$gift->canUse($this->user->identity)) + } + + if (!$gift->canUse($this->user->identity)) { $this->flashFail("err", tr("error_when_gifting"), tr("error_no_more_gifts")); - - if(!$user->canBeViewedBy($this->user->identity ?? NULL)) + } + + if (!$user->canBeViewedBy($this->user->identity ?? null)) { $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); + } $coinsLeft = $this->user->identity->getCoins() - $gift->getPrice(); - if($coinsLeft < 0) + if ($coinsLeft < 0) { $this->flashFail("err", tr("error_when_gifting"), tr("error_no_money")); - + } + $this->template->_template = "Gifts/Confirm.xml"; - if($_SERVER["REQUEST_METHOD"] !== "POST") { + if ($_SERVER["REQUEST_METHOD"] !== "POST") { $this->template->user = $user; $this->template->cat = $cat; $this->template->gift = $gift; return; } - - $comment = empty($c = $this->postParam("comment")) ? NULL : $c; + + $comment = empty($c = $this->postParam("comment")) ? null : $c; $notification = new GiftNotification($user, $this->user->identity, $gift, $comment); $notification->emit(); $this->user->identity->setCoins($coinsLeft); $this->user->identity->save(); $user->gift($this->user->identity, $gift, $comment, !is_null($this->postParam("anonymous"))); $gift->used(); - + $this->flash("succ", tr("gift_sent"), tr("gift_sent_desc", $user->getFirstName(), $gift->getPrice())); $this->redirect($user->getURL()); } - - function renderStub(): void + + public function renderStub(): void { $this->assertUserLoggedIn(); - + $act = $this->queryParam("act"); - switch($act) { + switch ($act) { case "pick": $this->renderGiftMenu(); break; - + case "menu": $this->renderGiftList(); break; - + case "confirm": $this->renderConfirmGift(); break; - + default: $this->notFound(); } } - - function renderGiftImage(int $id, int $timestamp): void + + public function renderGiftImage(int $id, int $timestamp): void { $gift = $this->gifts->get($id); - if(!$gift) + if (!$gift) { $this->notFound(); - + } + $image = $gift->getImage(); header("Cache-Control: no-transform, immutable"); header("Content-Length: " . strlen($image)); header("Content-Type: image/png"); exit($image); } - - function onStartup(): void + + public function onStartup(): void { - if(!OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"]) + if (!OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"]) { $this->flashFail("err", tr("error"), tr("feature_disabled")); - + } + parent::onStartup(); } } diff --git a/Web/Presenters/GroupPresenter.php b/Web/Presenters/GroupPresenter.php index cde025b5..1aa14213 100644 --- a/Web/Presenters/GroupPresenter.php +++ b/Web/Presenters/GroupPresenter.php @@ -1,5 +1,9 @@ -clubs = $clubs; - + parent::__construct(); } - - function renderView(int $id): void + + public function renderView(int $id): void { $club = $this->clubs->get($id); - if(!$club) { + if (!$club) { $this->notFound(); } else { if ($club->isBanned()) { $this->template->_template = "Group/Banned.xml"; } else { - $docs = (new Documents)->getDocumentsByOwner($club->getRealId()); - $this->template->albums = (new Albums)->getClubAlbums($club, 1, 3); - $this->template->albumsCount = (new Albums)->getClubAlbumsCount($club); - $this->template->topics = (new Topics)->getLastTopics($club, 3); - $this->template->topicsCount = (new Topics)->getClubTopicsCount($club); - $this->template->audios = (new Audios)->getRandomThreeAudiosByEntityId($club->getRealId()); - $this->template->audiosCount = (new Audios)->getClubCollectionSize($club); + $docs = (new Documents())->getDocumentsByOwner($club->getRealId()); + $this->template->albums = (new Albums())->getClubAlbums($club, 1, 3); + $this->template->albumsCount = (new Albums())->getClubAlbumsCount($club); + $this->template->topics = (new Topics())->getLastTopics($club, 3); + $this->template->topicsCount = (new Topics())->getClubTopicsCount($club); + $this->template->audios = (new Audios())->getRandomThreeAudiosByEntityId($club->getRealId()); + $this->template->audiosCount = (new Audios())->getClubCollectionSize($club); $this->template->docsCount = $docs->size(); $this->template->docs = $docs->offsetLimit(0, 2); } - if(!is_null($this->user->identity) && $club->getWallType() == 2) { - if(!$club->canBeModifiedBy($this->user->identity)) - $this->template->suggestedPostsCountByUser = (new Posts)->getSuggestedPostsCountByUser($club->getId(), $this->user->id); - else - $this->template->suggestedPostsCountByEveryone = (new Posts)->getSuggestedPostsCount($club->getId()); + if (!is_null($this->user->identity) && $club->getWallType() == 2) { + if (!$club->canBeModifiedBy($this->user->identity)) { + $this->template->suggestedPostsCountByUser = (new Posts())->getSuggestedPostsCountByUser($club->getId(), $this->user->id); + } else { + $this->template->suggestedPostsCountByEveryone = (new Posts())->getSuggestedPostsCount($club->getId()); + } } $this->template->club = $club; $this->template->ignore_status = $club->isIgnoredBy($this->user->identity); } } - - function renderCreate(): void + + public function renderCreate(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - - if($_SERVER["REQUEST_METHOD"] === "POST") { - if(!empty($this->postParam("name")) && mb_strlen(trim($this->postParam("name"))) > 0) - { - $club = new Club; + + if ($_SERVER["REQUEST_METHOD"] === "POST") { + if (!empty($this->postParam("name")) && mb_strlen(trim($this->postParam("name"))) > 0) { + $club = new Club(); $club->setName($this->postParam("name")); - $club->setAbout(empty($this->postParam("about")) ? NULL : $this->postParam("about")); + $club->setAbout(empty($this->postParam("about")) ? null : $this->postParam("about")); $club->setOwner($this->user->id); - + try { $club->save(); - } catch(\PDOException $ex) { - if($ex->getCode() == 23000) + } catch (\PDOException $ex) { + if ($ex->getCode() == 23000) { $this->flashFail("err", tr("error"), tr("error_on_server_side")); - else + } else { throw $ex; + } } - + $club->toggleSubscription($this->user->identity); $this->redirect("/club" . $club->getId()); - }else{ + } else { $this->flashFail("err", tr("error"), tr("error_no_group_name")); } } } - - function renderSub(): void + + public function renderSub(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - - if($_SERVER["REQUEST_METHOD"] !== "POST") exit("Invalid state"); - + + if ($_SERVER["REQUEST_METHOD"] !== "POST") { + exit("Invalid state"); + } + $club = $this->clubs->get((int) $this->postParam("id")); - if(!$club) exit("Invalid state"); - if ($club->isBanned()) $this->flashFail("err", tr("error"), tr("forbidden")); - + if (!$club) { + exit("Invalid state"); + } + if ($club->isBanned()) { + $this->flashFail("err", tr("error"), tr("forbidden")); + } + $club->toggleSubscription($this->user->identity); - + $this->redirect($club->getURL()); } - - function renderFollowers(int $id): void + + public function renderFollowers(int $id): void { $this->assertUserLoggedIn(); $this->template->club = $this->clubs->get($id); - if ($this->template->club->isBanned()) $this->flashFail("err", tr("error"), tr("forbidden")); + if ($this->template->club->isBanned()) { + $this->flashFail("err", tr("error"), tr("forbidden")); + } $this->template->onlyShowManagers = $this->queryParam("onlyAdmins") == "1"; - if($this->template->onlyShowManagers) { - $this->template->followers = NULL; + if ($this->template->onlyShowManagers) { + $this->template->followers = null; $this->template->managers = $this->template->club->getManagers((int) ($this->queryParam("p") ?? 1), !$this->template->club->canBeModifiedBy($this->user->identity)); - if($this->template->club->canBeModifiedBy($this->user->identity) || !$this->template->club->isOwnerHidden()) { + if ($this->template->club->canBeModifiedBy($this->user->identity) || !$this->template->club->isOwnerHidden()) { $this->template->managers = array_merge([$this->template->club->getOwner()], iterator_to_array($this->template->managers)); } $this->template->count = $this->template->club->getManagersCount(); } else { $this->template->followers = $this->template->club->getFollowers((int) ($this->queryParam("p") ?? 1)); - $this->template->managers = NULL; + $this->template->managers = null; $this->template->count = $this->template->club->getFollowersCount(); } @@ -126,136 +139,145 @@ final class GroupPresenter extends OpenVKPresenter "perPage" => OPENVK_DEFAULT_PER_PAGE, ]; } - - function renderModifyAdmin(int $id): void + + public function renderModifyAdmin(int $id): void { $user = is_null($this->queryParam("user")) ? $this->postParam("user") : $this->queryParam("user"); $comment = $this->postParam("comment"); $removeComment = $this->postParam("removeComment") === "1"; - $hidden = ["0" => false, "1" => true][$this->queryParam("hidden")] ?? NULL; + $hidden = ["0" => false, "1" => true][$this->queryParam("hidden")] ?? null; //$index = $this->queryParam("index"); - if(!$user) + if (!$user) { $this->badRequest(); - + } + $club = $this->clubs->get($id); - if ($club->isBanned()) $this->flashFail("err", tr("error"), tr("forbidden")); + if ($club->isBanned()) { + $this->flashFail("err", tr("error"), tr("forbidden")); + } - $user = (new Users)->get((int) $user); - if(!$user || !$club) + $user = (new Users())->get((int) $user); + if (!$user || !$club) { $this->notFound(); - - if(!$club->canBeModifiedBy($this->user->identity ?? NULL)) - $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied")); + } - if(!is_null($hidden)) { - if($club->getOwner()->getId() == $user->getId()) { + if (!$club->canBeModifiedBy($this->user->identity ?? null)) { + $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied")); + } + + if (!is_null($hidden)) { + if ($club->getOwner()->getId() == $user->getId()) { $club->setOwner_Hidden($hidden); $club->save(); } else { - $manager = (new Managers)->getByUserAndClub($user->getId(), $club->getId()); + $manager = (new Managers())->getByUserAndClub($user->getId(), $club->getId()); $manager->setHidden($hidden); $manager->save(); } - if($club->getManagersCount(true) == 0) { + if ($club->getManagersCount(true) == 0) { $club->setAdministrators_List_Display(2); $club->save(); } - if($hidden) { + if ($hidden) { $this->flashFail("succ", tr("success_action"), tr("x_is_now_hidden", $user->getCanonicalName())); } else { $this->flashFail("succ", tr("success_action"), tr("x_is_now_showed", $user->getCanonicalName())); } - } elseif($removeComment) { - if($club->getOwner()->getId() == $user->getId()) { + } elseif ($removeComment) { + if ($club->getOwner()->getId() == $user->getId()) { $club->setOwner_Comment(null); $club->save(); } else { - $manager = (new Managers)->getByUserAndClub($user->getId(), $club->getId()); + $manager = (new Managers())->getByUserAndClub($user->getId(), $club->getId()); $manager->setComment(null); $manager->save(); } $this->flashFail("succ", tr("success_action"), tr("comment_is_deleted")); - } elseif($comment) { - if(mb_strlen($comment) > 36) { + } elseif ($comment) { + if (mb_strlen($comment) > 36) { $commentLength = (string) mb_strlen($comment); $this->flashFail("err", tr("error"), tr("comment_is_too_long", $commentLength)); } - if($club->getOwner()->getId() == $user->getId()) { + if ($club->getOwner()->getId() == $user->getId()) { $club->setOwner_Comment($comment); $club->save(); } else { - $manager = (new Managers)->getByUserAndClub($user->getId(), $club->getId()); + $manager = (new Managers())->getByUserAndClub($user->getId(), $club->getId()); $manager->setComment($comment); $manager->save(); } $this->flashFail("succ", tr("success_action"), tr("comment_is_changed")); - }else{ - if($club->canBeModifiedBy($user)) { + } else { + if ($club->canBeModifiedBy($user)) { $club->removeManager($user); $this->flashFail("succ", tr("success_action"), tr("x_no_more_admin", $user->getCanonicalName())); } else { $club->addManager($user); - + (new ClubModeratorNotification($user, $club, $this->user->identity))->emit(); $this->flashFail("succ", tr("success_action"), tr("x_is_admin", $user->getCanonicalName())); } } - + } - - function renderEdit(int $id): void + + public function renderEdit(int $id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - + $club = $this->clubs->get($id); - if(!$club || !$club->canBeModifiedBy($this->user->identity)) + if (!$club || !$club->canBeModifiedBy($this->user->identity)) { $this->notFound(); - else if ($club->isBanned()) + } elseif ($club->isBanned()) { $this->flashFail("err", tr("error"), tr("forbidden")); - else + } else { $this->template->club = $club; - - if($_SERVER["REQUEST_METHOD"] === "POST") { - if(!$club->setShortcode( empty($this->postParam("shortcode")) ? NULL : $this->postParam("shortcode") )) + } + + if ($_SERVER["REQUEST_METHOD"] === "POST") { + if (!$club->setShortcode(empty($this->postParam("shortcode")) ? null : $this->postParam("shortcode"))) { $this->flashFail("err", tr("error"), tr("error_shorturl_incorrect")); - + } + $club->setName((empty($this->postParam("name")) || mb_strlen(trim($this->postParam("name"))) === 0) ? $club->getName() : $this->postParam("name")); - $club->setAbout(empty($this->postParam("about")) ? NULL : $this->postParam("about")); + $club->setAbout(empty($this->postParam("about")) ? null : $this->postParam("about")); try { - $club->setWall(empty($this->postParam("wall")) ? 0 : (int)$this->postParam("wall")); - } catch(\Exception $e) { + $club->setWall(empty($this->postParam("wall")) ? 0 : (int) $this->postParam("wall")); + } catch (\Exception $e) { $this->flashFail("err", tr("error"), tr("error_invalid_wall_value")); } - + $club->setAdministrators_List_Display(empty($this->postParam("administrators_list_display")) ? 0 : $this->postParam("administrators_list_display")); - $club->setEveryone_Can_Create_Topics(empty($this->postParam("everyone_can_create_topics")) ? 0 : 1); + $club->setEveryone_Can_Create_Topics(empty($this->postParam("everyone_can_create_topics")) ? 0 : 1); $club->setDisplay_Topics_Above_Wall(empty($this->postParam("display_topics_above_wall")) ? 0 : 1); $club->setEveryone_can_upload_audios(empty($this->postParam("upload_audios")) ? 0 : 1); if (!$club->isHidingFromGlobalFeedEnforced()) { $club->setHide_From_Global_Feed(empty($this->postParam("hide_from_global_feed") ? 0 : 1)); } - + $website = $this->postParam("website") ?? ""; - if(empty($website)) - $club->setWebsite(NULL); - else + if (empty($website)) { + $club->setWebsite(null); + } else { $club->setWebsite((!parse_url($website, PHP_URL_SCHEME) ? "https://" : "") . $website); - - if($_FILES["ava"]["error"] === UPLOAD_ERR_OK) { - $photo = new Photo; + } + + if ($_FILES["ava"]["error"] === UPLOAD_ERR_OK) { + $photo = new Photo(); try { $anon = OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["enable"]; - if($anon && $this->user->id === $club->getOwner()->getId()) - $anon = $club->isOwnerHidden(); - else if($anon) + if ($anon && $this->user->id === $club->getOwner()->getId()) { + $anon = $club->isOwnerHidden(); + } elseif ($anon) { $anon = $club->getManager($this->user->identity)->isHidden(); + } $photo->setOwner($this->user->id); $photo->setDescription("Profile image"); @@ -263,46 +285,49 @@ final class GroupPresenter extends OpenVKPresenter $photo->setCreated(time()); $photo->setAnonymous($anon); $photo->save(); - - (new Albums)->getClubAvatarAlbum($club)->addPhoto($photo); - } catch(ISE $ex) { + + (new Albums())->getClubAvatarAlbum($club)->addPhoto($photo); + } catch (ISE $ex) { $name = $album->getName(); $this->flashFail("err", tr("error"), tr("error_when_uploading_photo")); } } - + try { $club->save(); - } catch(\PDOException $ex) { - if($ex->getCode() == 23000) + } catch (\PDOException $ex) { + if ($ex->getCode() == 23000) { $this->flashFail("err", tr("error"), tr("error_on_server_side")); - else + } else { throw $ex; + } } - + $this->flash("succ", tr("changes_saved"), tr("new_changes_desc")); } } - - function renderSetAvatar(int $id) + + public function renderSetAvatar(int $id) { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); $club = $this->clubs->get($id); - if(!$club || $club->isBanned() || !$club->canBeModifiedBy($this->user->identity)) - $this->flashFail("err", tr("error"), tr("forbidden"), NULL, true); + if (!$club || $club->isBanned() || !$club->canBeModifiedBy($this->user->identity)) { + $this->flashFail("err", tr("error"), tr("forbidden"), null, true); + } - if($_SERVER["REQUEST_METHOD"] === "POST" && $_FILES["blob"]["error"] === UPLOAD_ERR_OK) { + if ($_SERVER["REQUEST_METHOD"] === "POST" && $_FILES["blob"]["error"] === UPLOAD_ERR_OK) { try { - $photo = new Photo; - + $photo = new Photo(); + $anon = OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["enable"]; - if($anon && $this->user->id === $club->getOwner()->getId()) - $anon = $club->isOwnerHidden(); - else if($anon) + if ($anon && $this->user->id === $club->getOwner()->getId()) { + $anon = $club->isOwnerHidden(); + } elseif ($anon) { $anon = $club->getManager($this->user->identity)->isHidden(); + } $photo->setOwner($this->user->id); $photo->setDescription("Club image"); @@ -310,12 +335,12 @@ final class GroupPresenter extends OpenVKPresenter $photo->setCreated(time()); $photo->setAnonymous($anon); $photo->save(); - - (new Albums)->getClubAvatarAlbum($club)->addPhoto($photo); - if($this->postParam("on_wall") == 1) { - $post = new Post; - + (new Albums())->getClubAvatarAlbum($club)->addPhoto($photo); + + if ($this->postParam("on_wall") == 1) { + $post = new Post(); + $post->setOwner($this->user->id); $post->setWall($club->getId() * -1); $post->setCreated(time()); @@ -331,8 +356,8 @@ final class GroupPresenter extends OpenVKPresenter $post->attach($photo); } - } catch(\Throwable $ex) { - $this->flashFail("err", tr("error"), tr("error_when_uploading_photo"), NULL, true); + } catch (\Throwable $ex) { + $this->flashFail("err", tr("error"), tr("error_when_uploading_photo"), null, true); } $this->returnJson([ @@ -345,127 +370,143 @@ final class GroupPresenter extends OpenVKPresenter } } - function renderDeleteAvatar(int $id) { + public function renderDeleteAvatar(int $id) + { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); $club = $this->clubs->get($id); - if(!$club || $club->isBanned() || !$club->canBeModifiedBy($this->user->identity)) - $this->flashFail("err", tr("error"), tr("forbidden"), NULL, true); + if (!$club || $club->isBanned() || !$club->canBeModifiedBy($this->user->identity)) { + $this->flashFail("err", tr("error"), tr("forbidden"), null, true); + } $avatar = $club->getAvatarPhoto(); - if(!$avatar) - $this->flashFail("succ", tr("error"), "no avatar bro", NULL, true); + if (!$avatar) { + $this->flashFail("succ", tr("error"), "no avatar bro", null, true); + } $avatar->isolate(); $newAvatar = $club->getAvatarPhoto(); - if(!$newAvatar) + if (!$newAvatar) { $this->returnJson([ "success" => true, "has_new_photo" => false, - "new_photo" => NULL, + "new_photo" => null, "url" => "/assets/packages/static/openvk/img/camera_200.png", ]); - else + } else { $this->returnJson([ "success" => true, "has_new_photo" => true, "new_photo" => $newAvatar->getPrettyId(), "url" => $newAvatar->getURL(), ]); + } } - function renderEditBackdrop(int $id): void + public function renderEditBackdrop(int $id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - + $club = $this->clubs->get($id); - if(!$club || !$club->canBeModifiedBy($this->user->identity)) + if (!$club || !$club->canBeModifiedBy($this->user->identity)) { $this->notFound(); - else + } else { $this->template->club = $club; - - if($_SERVER["REQUEST_METHOD"] !== "POST") + } + + if ($_SERVER["REQUEST_METHOD"] !== "POST") { return; - - if($this->postParam("subact") === "remove") { + } + + if ($this->postParam("subact") === "remove") { $club->unsetBackDropPictures(); $club->save(); $this->flashFail("succ", tr("backdrop_succ_rem"), tr("backdrop_succ_desc")); # will exit } - - $pic1 = $pic2 = NULL; + + $pic1 = $pic2 = null; try { - if($_FILES["backdrop1"]["error"] !== UPLOAD_ERR_NO_FILE) + if ($_FILES["backdrop1"]["error"] !== UPLOAD_ERR_NO_FILE) { $pic1 = Photo::fastMake($this->user->id, "Profile backdrop (system)", $_FILES["backdrop1"]); - - if($_FILES["backdrop2"]["error"] !== UPLOAD_ERR_NO_FILE) + } + + if ($_FILES["backdrop2"]["error"] !== UPLOAD_ERR_NO_FILE) { $pic2 = Photo::fastMake($this->user->id, "Profile backdrop (system)", $_FILES["backdrop2"]); - } catch(InvalidStateException $e) { + } + } catch (InvalidStateException $e) { $this->flashFail("err", tr("backdrop_error_title"), tr("backdrop_error_no_media")); } - - if($pic1 == $pic2 && is_null($pic1)) + + if ($pic1 == $pic2 && is_null($pic1)) { $this->flashFail("err", tr("backdrop_error_title"), tr("backdrop_error_no_media")); - + } + $club->setBackDropPictures($pic1, $pic2); $club->save(); $this->flashFail("succ", tr("backdrop_succ"), tr("backdrop_succ_desc")); } - - function renderStatistics(int $id): void + + public function renderStatistics(int $id): void { $this->assertUserLoggedIn(); - - if(!eventdb()) + + if (!eventdb()) { $this->flashFail("err", tr("connection_error"), tr("connection_error_desc")); - + } + $club = $this->clubs->get($id); - if(!$club->canBeModifiedBy($this->user->identity)) + if (!$club->canBeModifiedBy($this->user->identity)) { $this->notFound(); - else if ($club->isBanned()) + } elseif ($club->isBanned()) { $this->flashFail("err", tr("error"), tr("forbidden")); - else + } else { $this->template->club = $club; - + } + $this->template->reach = $club->getPostViewStats(true); $this->template->views = $club->getPostViewStats(false); } - function renderAdmin(int $clb, int $id): void + public function renderAdmin(int $clb, int $id): void { $this->assertUserLoggedIn(); - $manager = (new Managers)->get($id); - if($manager->getClub()->canBeModifiedBy($this->user->identity)){ + $manager = (new Managers())->get($id); + if ($manager->getClub()->canBeModifiedBy($this->user->identity)) { $this->template->manager = $manager; $this->template->club = $manager->getClub(); - }else{ + } else { $this->notFound(); } } - function renderChangeOwner(int $id, int $newOwnerId): void + public function renderChangeOwner(int $id, int $newOwnerId): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - if($_SERVER['REQUEST_METHOD'] !== "POST") + if ($_SERVER['REQUEST_METHOD'] !== "POST") { $this->redirect("/groups" . $this->user->id); + } - if(!Authenticator::verifyHash($this->postParam("password"), $this->user->identity->getChandlerUser()->getRaw()->passwordHash)) + if (!Authenticator::verifyHash($this->postParam("password"), $this->user->identity->getChandlerUser()->getRaw()->passwordHash)) { $this->flashFail("err", tr("error"), tr("incorrect_password")); + } $club = $this->clubs->get($id); - if ($club->isBanned()) $this->flashFail("err", tr("error"), tr("forbidden")); - $newOwner = (new Users)->get($newOwnerId); - if($this->user->id !== $club->getOwner()->getId()) + if ($club->isBanned()) { $this->flashFail("err", tr("error"), tr("forbidden")); + } + $newOwner = (new Users())->get($newOwnerId); + if ($this->user->id !== $club->getOwner()->getId()) { + $this->flashFail("err", tr("error"), tr("forbidden")); + } $club->setOwner($newOwnerId); @@ -485,33 +526,34 @@ final class GroupPresenter extends OpenVKPresenter $this->flashFail("succ", tr("information_-1"), tr("group_owner_setted", $newOwner->getCanonicalName(), $club->getName())); } - function renderSuggested(int $id): void + public function renderSuggested(int $id): void { $this->assertUserLoggedIn(); $club = $this->clubs->get($id); - if(!$club) + if (!$club) { $this->notFound(); - else + } else { $this->template->club = $club; + } - if($club->getWallType() == 0) { + if ($club->getWallType() == 0) { $this->flash("err", tr("error_suggestions"), tr("error_suggestions_closed")); - $this->redirect("/club".$club->getId()); + $this->redirect("/club" . $club->getId()); } - - if($club->getWallType() == 1) { + + if ($club->getWallType() == 1) { $this->flash("err", tr("error_suggestions"), tr("error_suggestions_open")); - $this->redirect("/club".$club->getId()); + $this->redirect("/club" . $club->getId()); } - - if(!$club->canBeModifiedBy($this->user->identity)) { - $this->template->posts = iterator_to_array((new Posts)->getSuggestedPostsByUser($club->getId(), $this->user->id, (int) ($this->queryParam("p") ?? 1))); - $this->template->count = (new Posts)->getSuggestedPostsCountByUser($club->getId(), $this->user->id); + + if (!$club->canBeModifiedBy($this->user->identity)) { + $this->template->posts = iterator_to_array((new Posts())->getSuggestedPostsByUser($club->getId(), $this->user->id, (int) ($this->queryParam("p") ?? 1))); + $this->template->count = (new Posts())->getSuggestedPostsCountByUser($club->getId(), $this->user->id); $this->template->type = "my"; } else { - $this->template->posts = iterator_to_array((new Posts)->getSuggestedPosts($club->getId(), (int) ($this->queryParam("p") ?? 1))); - $this->template->count = (new Posts)->getSuggestedPostsCount($club->getId()); + $this->template->posts = iterator_to_array((new Posts())->getSuggestedPosts($club->getId(), (int) ($this->queryParam("p") ?? 1))); + $this->template->count = (new Posts())->getSuggestedPostsCount($club->getId()); $this->template->type = "everyone"; } diff --git a/Web/Presenters/HelloPresenter.php b/Web/Presenters/HelloPresenter.php index 32f0c74e..f58ef8f6 100644 --- a/Web/Presenters/HelloPresenter.php +++ b/Web/Presenters/HelloPresenter.php @@ -1,10 +1,14 @@ -template->name = $name; } diff --git a/Web/Presenters/InternalAPIPresenter.php b/Web/Presenters/InternalAPIPresenter.php index 72546506..b33f159c 100644 --- a/Web/Presenters/InternalAPIPresenter.php +++ b/Web/Presenters/InternalAPIPresenter.php @@ -1,5 +1,9 @@ - hexdec(hash("crc32b", (string) time())), ])); } - + private function succ($payload): void { exit(MessagePack::pack([ @@ -27,10 +31,10 @@ final class InternalAPIPresenter extends OpenVKPresenter "id" => hexdec(hash("crc32b", (string) time())), ])); } - - function renderRoute(): void + + public function renderRoute(): void { - if($_SERVER["REQUEST_METHOD"] !== "POST") { + if ($_SERVER["REQUEST_METHOD"] !== "POST") { header("HTTP/1.1 405 Method Not Allowed"); exit("ты дебил это точка апи"); } @@ -39,88 +43,92 @@ final class InternalAPIPresenter extends OpenVKPresenter } catch (\Exception $ex) { $this->fail(-32700, "Parse error"); } - - if(is_null($input->brpc ?? NULL) || is_null($input->method ?? NULL)) + + if (is_null($input->brpc ?? null) || is_null($input->method ?? null)) { $this->fail(-32600, "Invalid BIN-RPC"); - else if($input->brpc !== 1) + } elseif ($input->brpc !== 1) { $this->fail(-32610, "Invalid version"); - + } + $method = explode(".", $input->method); - if(sizeof($method) !== 2) + if (sizeof($method) !== 2) { $this->fail(-32601, "Procedure not found"); - + } + [$class, $method] = $method; $class = '\openvk\ServiceAPI\\' . $class; - if(!class_exists($class)) + if (!class_exists($class)) { $this->fail(-32601, "Procedure not found"); - - $handler = new $class(is_null($this->user) ? NULL : $this->user->identity); - if(!is_callable([$handler, $method])) + } + + $handler = new $class(is_null($this->user) ? null : $this->user->identity); + if (!is_callable([$handler, $method])) { $this->fail(-32601, "Procedure not found"); - + } + try { - $params = array_merge($input->params ?? [], [function($data) { + $params = array_merge($input->params ?? [], [function ($data) { $this->succ($data); - }, function(int $errno, string $errstr) { + }, function (int $errno, string $errstr) { $this->fail($errno, $errstr); }]); $handler->{$method}(...$params); - } catch(\TypeError $te) { + } catch (\TypeError $te) { $this->fail(-32602, "Invalid params"); - } catch(\Exception $ex) { + } catch (\Exception $ex) { $this->fail(-32603, "Uncaught " . get_class($ex)); } } - function renderTimezone() { - if($_SERVER["REQUEST_METHOD"] !== "POST") { + public function renderTimezone() + { + if ($_SERVER["REQUEST_METHOD"] !== "POST") { header("HTTP/1.1 405 Method Not Allowed"); exit("ты дебил это метод апи"); } $sessionOffset = Session::i()->get("_timezoneOffset"); - if(is_numeric($this->postParam("timezone", false))) { + if (is_numeric($this->postParam("timezone", false))) { $postTZ = intval($this->postParam("timezone", false)); if ($postTZ != $sessionOffset || $sessionOffset == null) { - Session::i()->set("_timezoneOffset", $postTZ ? $postTZ : 3 * MINUTE ); + Session::i()->set("_timezoneOffset", $postTZ ? $postTZ : 3 * MINUTE); $this->returnJson([ - "success" => 1 # If it's new value + "success" => 1, # If it's new value ]); } else { $this->returnJson([ - "success" => 2 # If it's the same value (if for some reason server will call this func) + "success" => 2, # If it's the same value (if for some reason server will call this func) ]); } } else { $this->returnJson([ - "success" => 0 + "success" => 0, ]); } } - function renderGetPhotosFromPost(int $owner_id, int $post_id) { - if($_SERVER["REQUEST_METHOD"] !== "POST") { + public function renderGetPhotosFromPost(int $owner_id, int $post_id) + { + if ($_SERVER["REQUEST_METHOD"] !== "POST") { header("HTTP/1.1 405 Method Not Allowed"); exit("иди нахуй заебал"); } - if($this->postParam("parentType", false) == "post") { - $post = (new Posts)->getPostById($owner_id, $post_id, true); + if ($this->postParam("parentType", false) == "post") { + $post = (new Posts())->getPostById($owner_id, $post_id, true); } else { - $post = (new Comments)->get($post_id); + $post = (new Comments())->get($post_id); } - - if(is_null($post)) { + + if (is_null($post)) { $this->returnJson([ - "success" => 0 + "success" => 0, ]); } else { $response = []; $attachments = $post->getChildren(); - foreach($attachments as $attachment) - { - if($attachment instanceof \openvk\Web\Models\Entities\Photo) - { + foreach ($attachments as $attachment) { + if ($attachment instanceof \openvk\Web\Models\Entities\Photo) { $response[$attachment->getPrettyId()] = [ "url" => $attachment->getURLBySizeId('larger'), "id" => $attachment->getPrettyId(), @@ -129,35 +137,36 @@ final class InternalAPIPresenter extends OpenVKPresenter } $this->returnJson([ "success" => 1, - "body" => $response + "body" => $response, ]); } } - function renderGetPostTemplate(int $owner_id, int $post_id) { - if($_SERVER["REQUEST_METHOD"] !== "POST") { + public function renderGetPostTemplate(int $owner_id, int $post_id) + { + if ($_SERVER["REQUEST_METHOD"] !== "POST") { header("HTTP/1.1 405 Method Not Allowed"); exit("ты‍ не по адресу"); } $type = $this->queryParam("type", false); - if($type == "post") { - $post = (new Posts)->getPostById($owner_id, $post_id, true); + if ($type == "post") { + $post = (new Posts())->getPostById($owner_id, $post_id, true); } else { - $post = (new Comments)->get($post_id); + $post = (new Comments())->get($post_id); } - if(!$post || !$post->canBeEditedBy($this->user->identity)) { + if (!$post || !$post->canBeEditedBy($this->user->identity)) { exit(''); } header("Content-Type: text/plain"); - - if($type == 'post') { + + if ($type == 'post') { $this->template->_template = 'components/post.xml'; $this->template->post = $post; $this->template->commentSection = false; - } elseif($type == 'comment') { + } elseif ($type == 'comment') { $this->template->_template = 'components/comment.xml'; $this->template->comment = $post; } else { diff --git a/Web/Presenters/MaintenancePresenter.php b/Web/Presenters/MaintenancePresenter.php index d4a5a6ef..7f8144e6 100644 --- a/Web/Presenters/MaintenancePresenter.php +++ b/Web/Presenters/MaintenancePresenter.php @@ -1,4 +1,5 @@ flashFail("err", tr("error"), tr("forbidden")); + } $this->template->name = [ "photos" => tr("my_photos"), @@ -24,12 +26,9 @@ final class MaintenancePresenter extends OpenVKPresenter "notes" => tr("my_notes"), "notification" => tr("my_feedback"), "support" => tr("menu_support"), - "topics" => tr("topics") + "topics" => tr("topics"), ][$name] ?? $name; } - function renderAll(): void - { - - } + public function renderAll(): void {} } diff --git a/Web/Presenters/MessengerPresenter.php b/Web/Presenters/MessengerPresenter.php index cec99cff..70054620 100644 --- a/Web/Presenters/MessengerPresenter.php +++ b/Web/Presenters/MessengerPresenter.php @@ -1,5 +1,9 @@ -messages = $messages; $this->signaler = SignalManager::i(); parent::__construct(); } - + private function getCorrespondent(int $id): object { - if($id > 0) - return (new Users)->get($id); - else if($id < 0) - return (new Clubs)->get(abs($id)); - else if($id === 0) + if ($id > 0) { + return (new Users())->get($id); + } elseif ($id < 0) { + return (new Clubs())->get(abs($id)); + } elseif ($id === 0) { return $this->user->identity; + } } - - function renderIndex(): void + + public function renderIndex(): void { $this->assertUserLoggedIn(); - if(isset($_GET["sel"])) + if (isset($_GET["sel"])) { $this->pass("openvk!Messenger->app", $_GET["sel"]); - + } + $page = (int) ($_GET["p"] ?? 1); $correspondences = iterator_to_array($this->messages->getCorrespondencies($this->user->identity, $page)); @@ -49,67 +55,69 @@ final class MessengerPresenter extends OpenVKPresenter "perPage" => OPENVK_DEFAULT_PER_PAGE, ]; } - - function renderApp(int $sel): void + + public function renderApp(int $sel): void { $this->assertUserLoggedIn(); - - $correspondent = $this->getCorrespondent($sel); - if(!$correspondent) - $this->notFound(); - if(!$this->user->identity->getPrivacyPermission('messages.write', $correspondent)) - { + $correspondent = $this->getCorrespondent($sel); + if (!$correspondent) { + $this->notFound(); + } + + if (!$this->user->identity->getPrivacyPermission('messages.write', $correspondent)) { $this->flash("err", tr("warning"), tr("user_may_not_reply")); } - + $this->template->disable_ajax = 1; $this->template->selId = $sel; $this->template->correspondent = $correspondent; } - - function renderEvents(int $randNum): void + + public function renderEvents(int $randNum): void { $this->assertUserLoggedIn(); - + header("Content-Type: application/json"); - $this->signaler->listen(function($event, $id) { + $this->signaler->listen(function ($event, $id) { exit(json_encode([[ "UUID" => $id, "event" => $event->getLongPoolSummary(), ]])); }, $this->user->id); } - - function renderVKEvents(int $id): void + + public function renderVKEvents(int $id): void { header("Access-Control-Allow-Origin: *"); header("Content-Type: application/json"); - - if($this->queryParam("act") !== "a_check") + + if ($this->queryParam("act") !== "a_check") { exit(header("HTTP/1.1 400 Bad Request")); - else if(!$this->queryParam("key")) + } elseif (!$this->queryParam("key")) { exit(header("HTTP/1.1 403 Forbidden")); - + } + $key = $this->queryParam("key"); $payload = hex2bin(substr($key, 0, 16)); $signature = hex2bin(substr($key, 16)); - if(($signature ^ ( ~CHANDLER_ROOT_CONF["security"]["secret"] | ((string) $id))) !== $payload) { + if (($signature ^ (~CHANDLER_ROOT_CONF["security"]["secret"] | ((string) $id))) !== $payload) { exit(json_encode([ "failed" => 3, ])); } - + $legacy = $this->queryParam("version") < 3; $time = intval($this->queryParam("wait")); - - if($time > 60) + + if ($time > 60) { $time = 60; - elseif($time == 0) - $time = 25; // default - - $this->signaler->listen(function($event, $eId) use ($id) { + } elseif ($time == 0) { + $time = 25; + } // default + + $this->signaler->listen(function ($event, $eId) use ($id) { exit(json_encode([ "ts" => time(), "updates" => [ @@ -118,43 +126,46 @@ final class MessengerPresenter extends OpenVKPresenter ])); }, $id, $time); } - - function renderApiGetMessages(int $sel, int $lastMsg): void + + public function renderApiGetMessages(int $sel, int $lastMsg): void { $this->assertUserLoggedIn(); - + $correspondent = $this->getCorrespondent($sel); - if(!$correspondent) + if (!$correspondent) { $this->notFound(); - + } + $messages = []; $correspondence = new Correspondence($this->user->identity, $correspondent); - foreach($correspondence->getMessages(1, $lastMsg === 0 ? NULL : $lastMsg, NULL, 0) as $message) + foreach ($correspondence->getMessages(1, $lastMsg === 0 ? null : $lastMsg, null, 0) as $message) { $messages[] = $message->simplify(); - + } + header("Content-Type: application/json"); exit(json_encode($messages)); } - - function renderApiWriteMessage(int $sel): void + + public function renderApiWriteMessage(int $sel): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - - if(empty($this->postParam("content"))) { + + if (empty($this->postParam("content"))) { header("HTTP/1.1 400 Bad Request"); exit("Argument error: param 'content' expected to be string, undefined given."); } - + $sel = $this->getCorrespondent($sel); - if($sel->getId() !== $this->user->id && !$sel->getPrivacyPermission('messages.write', $this->user->identity)) + if ($sel->getId() !== $this->user->id && !$sel->getPrivacyPermission('messages.write', $this->user->identity)) { exit(header("HTTP/1.1 403 Forbidden")); - + } + $cor = new Correspondence($this->user->identity, $sel); - $msg = new Message; + $msg = new Message(); $msg->setContent($this->postParam("content")); $cor->sendMessage($msg); - + header("HTTP/1.1 202 Accepted"); header("Content-Type: application/json"); exit(json_encode($msg->simplify())); diff --git a/Web/Presenters/NoSpamPresenter.php b/Web/Presenters/NoSpamPresenter.php index 714cac93..4f49d3b1 100644 --- a/Web/Presenters/NoSpamPresenter.php +++ b/Web/Presenters/NoSpamPresenter.php @@ -1,4 +1,6 @@ -assertUserLoggedIn(); $this->assertPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0); @@ -62,24 +64,26 @@ final class NoSpamPresenter extends OpenVKPresenter foreach ($foundClasses as $class) { $r = new \ReflectionClass(NoSpamPresenter::ENTITIES_NAMESPACE . "\\$class"); - if (!$r->isAbstract() && $r->getName() !== NoSpamPresenter::ENTITIES_NAMESPACE . "\\Correspondence") + if (!$r->isAbstract() && $r->getName() !== NoSpamPresenter::ENTITIES_NAMESPACE . "\\Correspondence") { $models[] = $class; + } } $this->template->models = $models; - } else if ($mode === "templates") { + } elseif ($mode === "templates") { $this->template->_template = "NoSpam/Templates.xml"; $this->template->disable_ajax = 1; $filter = []; if ($this->queryParam("id")) { - $filter["id"] = (int)$this->queryParam("id"); + $filter["id"] = (int) $this->queryParam("id"); } - $this->template->templates = iterator_to_array((new NoSpamLogs)->getList($filter)); - } else if ($mode === "reports") { + $this->template->templates = iterator_to_array((new NoSpamLogs())->getList($filter)); + } elseif ($mode === "reports") { $this->redirect("/scumfeed"); } else { - $template = (new NoSpamLogs)->get((int)$this->postParam("id")); - if (!$template || $template->isRollbacked()) + $template = (new NoSpamLogs())->get((int) $this->postParam("id")); + if (!$template || $template->isRollbacked()) { $this->returnJson(["success" => false, "error" => "Шаблон не найден"]); + } $model = NoSpamPresenter::ENTITIES_NAMESPACE . "\\" . $template->getModel(); $items = $template->getItems(); @@ -89,10 +93,12 @@ final class NoSpamPresenter extends OpenVKPresenter $unbanned_ids = []; foreach ($items as $_item) { try { - $item = new $model; + $item = new $model(); $table_name = $item->getTableName(); - $item = $db->table($table_name)->get((int)$_item); - if (!$item) continue; + $item = $db->table($table_name)->get((int) $_item); + if (!$item) { + continue; + } $item = new $model($item); @@ -102,7 +108,7 @@ final class NoSpamPresenter extends OpenVKPresenter } if (in_array($template->getTypeRaw(), [2, 3])) { - $owner = NULL; + $owner = null; $methods = ["getOwner", "getUser", "getRecipient", "getInitiator"]; if (method_exists($item, "ban")) { @@ -138,30 +144,38 @@ final class NoSpamPresenter extends OpenVKPresenter } } - function renderSearch(): void + public function renderSearch(): void { $this->assertUserLoggedIn(); $this->assertPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0); $this->assertNoCSRF(); $this->willExecuteWriteAction(); - function searchByAdditionalParams(?string $table = NULL, ?string $where = NULL, ?string $ip = NULL, ?string $useragent = NULL, ?int $ts = NULL, ?int $te = NULL, $user = NULL) + function searchByAdditionalParams(?string $table = null, ?string $where = null, ?string $ip = null, ?string $useragent = null, ?int $ts = null, ?int $te = null, $user = null) { $db = DatabaseConnection::i()->getContext(); if ($table && ($ip || $useragent || $ts || $te || $user)) { $conditions = []; - if ($ip) $conditions[] = "`ip` REGEXP '$ip'"; - if ($useragent) $conditions[] = "`useragent` REGEXP '$useragent'"; - if ($ts) $conditions[] = "`ts` < $ts"; - if ($te) $conditions[] = "`ts` > $te"; + if ($ip) { + $conditions[] = "`ip` REGEXP '$ip'"; + } + if ($useragent) { + $conditions[] = "`useragent` REGEXP '$useragent'"; + } + if ($ts) { + $conditions[] = "`ts` < $ts"; + } + if ($te) { + $conditions[] = "`ts` > $te"; + } if ($user) { - $users = new Users; + $users = new Users(); - $_user = $users->getByChandlerUser((new ChandlerUsers)->getById($user)) - ?? $users->get((int)$user) + $_user = $users->getByChandlerUser((new ChandlerUsers())->getById($user)) + ?? $users->get((int) $user) ?? $users->getByAddress($user) - ?? NULL; + ?? null; if ($_user) { $conditions[] = "`user` = '" . $_user->getChandlerGUID() . "'"; @@ -180,10 +194,12 @@ final class NoSpamPresenter extends OpenVKPresenter $logs = $db->query("SELECT * FROM `ChandlerLogs` $whereStart $conditions GROUP BY `object_id`, `object_model`"); foreach ($logs as $log) { - $log = (new Logs)->get($log->id); + $log = (new Logs())->get($log->id); $object = $log->getObject()->unwrap(); - if (!$object) continue; + if (!$object) { + continue; + } if ($where) { if (str_starts_with($where, " AND")) { $where = substr_replace($where, "", 0, strlen(" AND")); @@ -214,16 +230,17 @@ final class NoSpamPresenter extends OpenVKPresenter $ip = addslashes($this->postParam("ip")); $useragent = addslashes($this->postParam("useragent")); $searchTerm = addslashes($this->postParam("q")); - $ts = (int)$this->postParam("ts"); - $te = (int)$this->postParam("te"); + $ts = (int) $this->postParam("ts"); + $te = (int) $this->postParam("te"); $user = addslashes($this->postParam("user")); if ($where) { $where = explode(";", $where)[0]; } - if (!$ip && !$useragent && !$searchTerm && !$ts && !$te && !$where && !$searchTerm && !$user) + if (!$ip && !$useragent && !$searchTerm && !$ts && !$te && !$where && !$searchTerm && !$user) { $this->returnJson(["success" => false, "error" => "Нет запроса. Заполните поле \"подстрока\" или введите запрос \"WHERE\" в поле под ним."]); + } $models = explode(",", $this->postParam("models")); @@ -233,7 +250,7 @@ final class NoSpamPresenter extends OpenVKPresenter continue; } - $model = new $model_name; + $model = new $model_name(); $c = new \ReflectionClass($model_name); if ($c->isAbstract() || $c->getName() == NoSpamPresenter::ENTITIES_NAMESPACE . "\\Correspondence") { @@ -257,7 +274,9 @@ final class NoSpamPresenter extends OpenVKPresenter $conditions = implode(" OR ", $conditions); $where = ($this->postParam("where") ? " AND ($conditions)" : "($conditions)"); - if ($need_deleted) $where .= " AND (`deleted` = 0)"; + if ($need_deleted) { + $where .= " AND (`deleted` = 0)"; + } } $rows = []; @@ -281,9 +300,9 @@ final class NoSpamPresenter extends OpenVKPresenter } } - if (!in_array((int)$this->postParam("ban"), [1, 2, 3])) { + if (!in_array((int) $this->postParam("ban"), [1, 2, 3])) { foreach ($rows as $key => $object) { - $object = (array)$object; + $object = (array) $object; $_obj = []; foreach ($object as $key => $value) { foreach ($columns as $column) { @@ -303,11 +322,13 @@ final class NoSpamPresenter extends OpenVKPresenter foreach ($rows as $object) { $object = new $model_name($db->table($table)->get($object->id)); - if (!$object) continue; + if (!$object) { + continue; + } $ids[] = $object->getId(); } - $log = new NoSpamLog; + $log = new NoSpamLog(); $log->setUser($this->user->id); $log->setModel($_model); if ($searchTerm) { @@ -315,7 +336,7 @@ final class NoSpamPresenter extends OpenVKPresenter } else { $log->setRequest($where); } - $log->setBan_Type((int)$this->postParam("ban")); + $log->setBan_Type((int) $this->postParam("ban")); $log->setCount(count($rows)); $log->setTime(time()); $log->setItems(implode(",", $ids)); @@ -324,9 +345,11 @@ final class NoSpamPresenter extends OpenVKPresenter $banned_ids = []; foreach ($rows as $object) { $object = new $model_name($db->table($table)->get($object->id)); - if (!$object) continue; + if (!$object) { + continue; + } - $owner = NULL; + $owner = null; $methods = ["getOwner", "getUser", "getRecipient", "getInitiator"]; if (method_exists($object, "ban")) { @@ -348,17 +371,18 @@ final class NoSpamPresenter extends OpenVKPresenter } } - if (in_array((int)$this->postParam("ban"), [2, 3])) { + if (in_array((int) $this->postParam("ban"), [2, 3])) { $reason = mb_strlen(trim($this->postParam("ban_reason"))) > 0 ? addslashes($this->postParam("ban_reason")) : ("**content-noSpamTemplate-" . $log->getId() . "**"); - $is_forever = (string)$this->postParam("is_forever") === "true"; - $unban_time = $is_forever ? 0 : (int)$this->postParam("unban_time") ?? NULL; + $is_forever = (string) $this->postParam("is_forever") === "true"; + $unban_time = $is_forever ? 0 : (int) $this->postParam("unban_time") ?? null; if ($owner) { $_id = ($owner instanceof Club ? $owner->getId() * -1 : $owner->getId()); if (!in_array($_id, $banned_ids)) { if ($owner instanceof User) { - if (!$unban_time && !$is_forever) + if (!$unban_time && !$is_forever) { $unban_time = time() + $owner->getNewBanTime(); + } $owner->ban($reason, false, $unban_time, $this->user->id); } else { @@ -370,8 +394,9 @@ final class NoSpamPresenter extends OpenVKPresenter } } - if (in_array((int)$this->postParam("ban"), [1, 3])) + if (in_array((int) $this->postParam("ban"), [1, 3])) { $object->delete(); + } } $processed++; diff --git a/Web/Presenters/NotesPresenter.php b/Web/Presenters/NotesPresenter.php index 37475013..ec51f238 100644 --- a/Web/Presenters/NotesPresenter.php +++ b/Web/Presenters/NotesPresenter.php @@ -1,5 +1,9 @@ -notes = $notes; - + parent::__construct(); } - - function renderList(int $owner): void + + public function renderList(int $owner): void { - $user = (new Users)->get($owner); - if(!$user) $this->notFound(); - if(!$user->getPrivacyPermission('notes.read', $this->user->identity ?? NULL)) + $user = (new Users())->get($owner); + if (!$user) { + $this->notFound(); + } + if (!$user->getPrivacyPermission('notes.read', $this->user->identity ?? null)) { $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); - - $this->template->page = (int)($this->queryParam("p") ?? 1); + } + + $this->template->page = (int) ($this->queryParam("p") ?? 1); $this->template->notes = $this->notes->getUserNotes($user, $this->template->page); $this->template->count = $this->notes->getUserNotesCount($user); $this->template->owner = $user; } - - function renderView(int $owner, int $note_id): void + + public function renderView(int $owner, int $note_id): void { $note = $this->notes->getNoteById($owner, $note_id); - if(!$note || $note->getOwner()->getId() !== $owner || $note->isDeleted()) + if (!$note || $note->getOwner()->getId() !== $owner || $note->isDeleted()) { $this->notFound(); - if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->user->identity ?? NULL)) + } + if (!$note->getOwner()->getPrivacyPermission('notes.read', $this->user->identity ?? null)) { $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); - if(!$note->canBeViewedBy($this->user->identity)) + } + if (!$note->canBeViewedBy($this->user->identity)) { $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); - + } + $this->template->cCount = $note->getCommentsCount(); $this->template->cPage = (int) ($this->queryParam("p") ?? 1); $this->template->comments = iterator_to_array($note->getComments($this->template->cPage)); $this->template->note = $note; } - - function renderPreView(): void + + public function renderPreView(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - - if($_SERVER["REQUEST_METHOD"] !== "POST") { + + if ($_SERVER["REQUEST_METHOD"] !== "POST") { header("HTTP/1.1 400 Bad Request"); exit; } - - if(empty($this->postParam("html")) || empty($this->postParam("title"))) { + + if (empty($this->postParam("html")) || empty($this->postParam("title"))) { header("HTTP/1.1 400 Bad Request"); exit(tr("note_preview_empty_err")); } - - $note = new Note; + + $note = new Note(); $note->setSource($this->postParam("html")); - + $this->flash("info", tr("note_preview_warn"), tr("note_preview_warn_details")); $this->template->title = $this->postParam("title"); $this->template->html = $note->getText(); } - - function renderCreate(): void + + public function renderCreate(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - + $id = $this->user->id; #TODO: when ACL'll be done, allow admins to edit users via ?GUID=(chandler guid) - - if(!$id) + + if (!$id) { $this->notFound(); - - if($_SERVER["REQUEST_METHOD"] === "POST") { - if(empty($this->postParam("name"))) { - $this->flashFail("err", tr("error"), tr("error_segmentation")); + } + + if ($_SERVER["REQUEST_METHOD"] === "POST") { + if (empty($this->postParam("name"))) { + $this->flashFail("err", tr("error"), tr("error_segmentation")); } - $note = new Note; + $note = new Note(); $note->setOwner($this->user->id); $note->setCreated(time()); $note->setName($this->postParam("name")); $note->setSource($this->postParam("html")); $note->setEdited(time()); $note->save(); - + $this->redirect("/note" . $this->user->id . "_" . $note->getVirtualId()); } } - function renderEdit(int $owner, int $note_id): void + public function renderEdit(int $owner, int $note_id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - + $note = $this->notes->getNoteById($owner, $note_id); - if(!$note || $note->getOwner()->getId() !== $owner || $note->isDeleted()) + if (!$note || $note->getOwner()->getId() !== $owner || $note->isDeleted()) { $this->notFound(); - if(is_null($this->user) || !$note->canBeModifiedBy($this->user->identity)) + } + if (is_null($this->user) || !$note->canBeModifiedBy($this->user->identity)) { $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied")); + } $this->template->note = $note; - - if($_SERVER["REQUEST_METHOD"] === "POST") { - if(empty($this->postParam("name"))) { - $this->flashFail("err", tr("error"), tr("error_segmentation")); + + if ($_SERVER["REQUEST_METHOD"] === "POST") { + if (empty($this->postParam("name"))) { + $this->flashFail("err", tr("error"), tr("error_segmentation")); } $note->setName($this->postParam("name")); $note->setSource($this->postParam("html")); - $note->setCached_Content(NULL); + $note->setCached_Content(null); $note->setEdited(time()); $note->save(); - + $this->redirect("/note" . $this->user->id . "_" . $note->getVirtualId()); } } - - function renderDelete(int $owner, int $id): void + + public function renderDelete(int $owner, int $id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); $this->assertNoCSRF(); - + $note = $this->notes->get($id); - if(!$note) $this->notFound(); - if($note->getOwner()->getId() . "_" . $note->getId() !== $owner . "_" . $id || $note->isDeleted()) $this->notFound(); - if(is_null($this->user) || !$note->canBeModifiedBy($this->user->identity)) + if (!$note) { + $this->notFound(); + } + if ($note->getOwner()->getId() . "_" . $note->getId() !== $owner . "_" . $id || $note->isDeleted()) { + $this->notFound(); + } + if (is_null($this->user) || !$note->canBeModifiedBy($this->user->identity)) { $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied")); - + } + $name = $note->getName(); $note->delete(); $this->flash("succ", tr("note_is_deleted"), tr("note_x_is_now_deleted", $name)); diff --git a/Web/Presenters/NotificationPresenter.php b/Web/Presenters/NotificationPresenter.php index 3bd7a321..fda3e3a4 100644 --- a/Web/Presenters/NotificationPresenter.php +++ b/Web/Presenters/NotificationPresenter.php @@ -1,18 +1,21 @@ -assertUserLoggedIn(); $archive = $this->queryParam("act") === "archived"; $count = $this->user->identity->getNotificationsCount($archive); - if($count == 0 && $this->queryParam("act") == NULL) { + if ($count == 0 && $this->queryParam("act") == null) { $mode = "archived"; $archive = true; } else { @@ -23,7 +26,7 @@ final class NotificationPresenter extends OpenVKPresenter $this->template->page = (int) ($this->queryParam("p") ?? 1); $this->template->iterator = iterator_to_array($this->user->identity->getNotifications($this->template->page, $archive)); $this->template->count = $count; - + $this->user->identity->updateNotificationOffset(); $this->user->identity->save(); } diff --git a/Web/Presenters/OpenVKPresenter.php b/Web/Presenters/OpenVKPresenter.php index 8b33b5a7..122e0966 100644 --- a/Web/Presenters/OpenVKPresenter.php +++ b/Web/Presenters/OpenVKPresenter.php @@ -1,5 +1,9 @@ -path; - + return "$path?" . http_build_query(array_merge($_GET, $data)); } - - protected function flash(string $type, string $title, ?string $message = NULL, ?int $code = NULL): void + + protected function flash(string $type, string $title, ?string $message = null, ?int $code = null): void { Session::i()->set("_error", json_encode([ "type" => $type, @@ -40,15 +44,16 @@ abstract class OpenVKPresenter extends SimplePresenter protected function setSessionTheme(string $theme, bool $once = false): void { - if($once) + if ($once) { Session::i()->set("_tempTheme", $theme); - else + } else { Session::i()->set("_sessionTheme", $theme); + } } - - protected function flashFail(string $type, string $title, ?string $message = NULL, ?int $code = NULL, bool $json = false): void + + protected function flashFail(string $type, string $title, ?string $message = null, ?int $code = null, bool $json = false): void { - if($json) { + if ($json) { $this->returnJson([ "success" => $type !== "err", "flash" => [ @@ -61,25 +66,25 @@ abstract class OpenVKPresenter extends SimplePresenter } else { $this->flash($type, $title, $message, $code); $referer = $_SERVER["HTTP_REFERER"] ?? "/"; - + $this->redirect($referer); } } - + protected function logInUserWithToken(): void { $header = $_SERVER["HTTP_AUTHORIZATION"] ?? ""; $token; - + preg_match("%Bearer (.*)$%", $header, $matches); $token = $matches[1] ?? ""; - $token = (new APITokens)->getByCode($token); - if(!$token) { + $token = (new APITokens())->getByCode($token); + if (!$token) { header("HTTP/1.1 401 Unauthorized"); header("Content-Type: application/json"); exit(json_encode(["error" => "The access token is invalid"])); } - + $this->user = (object) []; $this->user->identity = $token->getUser(); $this->user->raw = $this->user->identity->getChandlerUser(); @@ -87,95 +92,100 @@ abstract class OpenVKPresenter extends SimplePresenter $this->template->thisUser = $this->user->identity; $this->template->userTainted = false; } - + protected function assertUserLoggedIn(bool $returnUrl = true): void { - if(is_null($this->user)) { + if (is_null($this->user)) { $loginUrl = "/login"; - if($returnUrl && $_SERVER["REQUEST_METHOD"] === "GET") { + if ($returnUrl && $_SERVER["REQUEST_METHOD"] === "GET") { $currentUrl = function_exists("get_current_url") ? get_current_url() : $_SERVER["REQUEST_URI"]; $loginUrl .= "?jReturnTo=" . rawurlencode($currentUrl); } - + $this->flash("err", tr("login_required_error"), tr("login_required_error_comment")); - + $this->redirect($loginUrl); } } - + protected function hasPermission(string $model, string $action, int $context): bool { - if(is_null($this->user)) { - if($model !== "user") { + if (is_null($this->user)) { + if ($model !== "user") { $this->flash("info", tr("login_required_error"), tr("login_required_error_comment")); - + $this->redirect("/login"); } - + return ($action === "register" || $action === "login"); } - - return (bool) $this->user->raw->can($action)->model($model)->whichBelongsTo($context === -1 ? NULL : $context); + + return (bool) $this->user->raw->can($action)->model($model)->whichBelongsTo($context === -1 ? null : $context); } - + protected function assertPermission(string $model, string $action, int $context, bool $throw = false): void { - if($this->hasPermission($model, $action, $context)) return; - - if($throw) + if ($this->hasPermission($model, $action, $context)) { + return; + } + + if ($throw) { throw new SecurityPolicyViolationException("Permission error"); - else + } else { $this->flashFail("err", tr("not_enough_permissions"), tr("not_enough_permissions_comment")); + } } - + protected function assertCaptchaCheckPassed(): void { - if(!check_captcha()) + if (!check_captcha()) { $this->flashFail("err", tr("captcha_error"), tr("captcha_error_comment")); + } } - + protected function willExecuteWriteAction(bool $json = false): void { - $ip = (new IPs)->get(CONNECTING_IP); + $ip = (new IPs())->get(CONNECTING_IP); $res = $ip->rateLimit(); - - 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_RESET || $res === IP::RL_CANEXEC)) { + if ($res === IP::RL_BANNED && OPENVK_ROOT_CONF["openvk"]["preferences"]["security"]["rateLimits"]["autoban"]) { $this->user->identity->ban("Account has possibly been stolen", false); exit("Хакеры? Интересно..."); } - - $this->flashFail("err", tr("rate_limit_error"), tr("rate_limit_error_comment", OPENVK_ROOT_CONF["openvk"]["appearance"]["name"], $res), NULL, $json); + + $this->flashFail("err", tr("rate_limit_error"), tr("rate_limit_error_comment", OPENVK_ROOT_CONF["openvk"]["appearance"]["name"], $res), null, $json); } } - + protected function signal(object $event): bool { return (SignalManager::i())->triggerEvent($event, $this->user->id); } - + protected function logEvent(string $type, array $data): bool { $db = eventdb(); - if(!$db) + if (!$db) { return false; - + } + $data = array_merge([ "timestamp" => time(), "verified" => (int) true, ], $data); - $columns = implode(", ", array_map(function($col) { + $columns = implode(", ", array_map(function ($col) { return "`" . addslashes($col) . "`"; }, array_keys($data))); - $values = implode(", ", array_map(function($val) { + $values = implode(", ", array_map(function ($val) { return "'" . addslashes((string) (int) $val) . "'"; }, array_values($data))); - + $db->getConnection()->query("INSERT INTO " . $type . "s($columns) VALUES ($values);"); - + return true; } - + /** * @override */ @@ -183,52 +193,53 @@ abstract class OpenVKPresenter extends SimplePresenter { parent::sendmail($to, __DIR__ . "/../../Email/$template", $params); } - - function getTemplatingEngine(): TemplatingEngine + + public function getTemplatingEngine(): TemplatingEngine { $latte = parent::getTemplatingEngine(); - $latte->addFilter("translate", function($s) { + $latte->addFilter("translate", function ($s) { return tr($s); }); - + return $latte; } - - function onStartup(): void + + public function onStartup(): void { $user = Authenticator::i()->getUser(); - if(!$this->template) - $this->template = new \stdClass; - + if (!$this->template) { + $this->template = new \stdClass(); + } + $this->template->isXmas = intval(date('d')) >= 1 && date('m') == 12 || intval(date('d')) <= 15 && date('m') == 1 ? true : false; $this->template->isTimezoned = Session::i()->get("_timezoneOffset"); $userValidated = 0; $cacheTime = OPENVK_ROOT_CONF["openvk"]["preferences"]["nginxCacheTime"] ?? 0; - if(OPENVK_ROOT_CONF['openvk']['preferences']['news']['show']) { - $post = (new Posts)->getPostsFromUsersWall(-OPENVK_ROOT_CONF['openvk']['preferences']['news']['groupId'], 1, 1); + if (OPENVK_ROOT_CONF['openvk']['preferences']['news']['show']) { + $post = (new Posts())->getPostsFromUsersWall(-OPENVK_ROOT_CONF['openvk']['preferences']['news']['groupId'], 1, 1); $post = iterator_to_array($post)[0]; $text = wordwrap($post->getText(false), 150, '\n', false); $text = explode('\n', $text)[0]; - + $this->template->newsText = $text; $this->template->newsLink = '/wall' . $post->getPrettyId(); } - if(!is_null($user)) { + if (!is_null($user)) { $this->user = (object) []; $this->user->raw = $user; - $this->user->identity = (new Users)->getByChandlerUser($user); + $this->user->identity = (new Users())->getByChandlerUser($user); $this->user->id = $this->user->identity->getId(); $this->template->thisUser = $this->user->identity; $this->template->userTainted = $user->isTainted(); CurrentUser::get($this->user->identity, $_SERVER["REMOTE_ADDR"], $_SERVER["HTTP_USER_AGENT"]); - if($this->user->identity->isDeleted() && !$this->deactivationTolerant) { - if($this->user->identity->isDeactivated()) { + if ($this->user->identity->isDeleted() && !$this->deactivationTolerant) { + if ($this->user->identity->isDeactivated()) { header("HTTP/1.1 403 Forbidden"); $this->getTemplatingEngine()->render(__DIR__ . "/templates/@deactivated.xml", [ "thisUser" => $this->user->identity, @@ -237,14 +248,14 @@ abstract class OpenVKPresenter extends SimplePresenter ]); } else { Authenticator::i()->logout(); - Session::i()->set("_su", NULL); + Session::i()->set("_su", null); $this->flashFail("err", tr("error"), tr("profile_not_found")); $this->redirect("/"); } exit; } - if($this->user->identity->isBanned() && !$this->banTolerant) { + if ($this->user->identity->isBanned() && !$this->banTolerant) { header("HTTP/1.1 403 Forbidden"); $this->getTemplatingEngine()->render(__DIR__ . "/templates/@banned.xml", [ "thisUser" => $this->user->identity, @@ -255,7 +266,7 @@ abstract class OpenVKPresenter extends SimplePresenter } # ето для емейл уже надо (и по хорошему надо бы избавится от повторяющегося кода мда) - if(!$this->user->identity->isActivated() && !$this->activationTolerant) { + if (!$this->user->identity->isActivated() && !$this->activationTolerant) { header("HTTP/1.1 403 Forbidden"); $this->getTemplatingEngine()->render(__DIR__ . "/templates/@email.xml", [ "thisUser" => $this->user->identity, @@ -267,16 +278,16 @@ abstract class OpenVKPresenter extends SimplePresenter $userValidated = 1; $cacheTime = 0; # Force no cache - if(!property_exists($this, 'silent') && $this->user->identity->onlineStatus() == 0 && !($this->user->identity->isDeleted() || $this->user->identity->isBanned())) { + if (!property_exists($this, 'silent') && $this->user->identity->onlineStatus() == 0 && !($this->user->identity->isDeleted() || $this->user->identity->isBanned())) { $this->user->identity->setOnline(time()); - $this->user->identity->setClient_name(NULL); + $this->user->identity->setClient_name(null); $this->user->identity->save(false); } - $this->template->ticketAnsweredCount = (new Tickets)->getTicketsCountByUserId($this->user->id, 1); - if($user->can("write")->model("openvk\Web\Models\Entities\TicketReply")->whichBelongsTo(0)) { - $this->template->helpdeskTicketNotAnsweredCount = (new Tickets)->getTicketCount(0); - $this->template->reportNotAnsweredCount = (new Reports)->getReportsCount(0); + $this->template->ticketAnsweredCount = (new Tickets())->getTicketsCountByUserId($this->user->id, 1); + if ($user->can("write")->model("openvk\Web\Models\Entities\TicketReply")->whichBelongsTo(0)) { + $this->template->helpdeskTicketNotAnsweredCount = (new Tickets())->getTicketCount(0); + $this->template->reportNotAnsweredCount = (new Reports())->getReportsCount(0); } } @@ -293,47 +304,49 @@ abstract class OpenVKPresenter extends SimplePresenter $this->redirect("/maintenances/"); } } - - if($_SERVER['HTTP_X_OPENVK_AJAX_QUERY'] == '1' && $this->user->identity) { + + if ($_SERVER['HTTP_X_OPENVK_AJAX_QUERY'] == '1' && $this->user->identity) { error_reporting(0); header('Content-Type: text/plain; charset=UTF-8'); } parent::onStartup(); } - - function onBeforeRender(): void + + public function onBeforeRender(): void { parent::onBeforeRender(); - + $whichbrowser = new WhichBrowser\Parser(getallheaders()); $featurephonetheme = OPENVK_ROOT_CONF["openvk"]["preferences"]["defaultFeaturePhoneTheme"]; $mobiletheme = OPENVK_ROOT_CONF["openvk"]["preferences"]["defaultMobileTheme"]; - - if($featurephonetheme && $this->isOldThing($whichbrowser) && Session::i()->get("_tempTheme") == NULL) { + + if ($featurephonetheme && $this->isOldThing($whichbrowser) && Session::i()->get("_tempTheme") == null) { $this->setSessionTheme($featurephonetheme); - } elseif($mobiletheme && $whichbrowser->isType('mobile') && Session::i()->get("_tempTheme") == NULL) + } elseif ($mobiletheme && $whichbrowser->isType('mobile') && Session::i()->get("_tempTheme") == null) { $this->setSessionTheme($mobiletheme); - - $theme = NULL; - if(Session::i()->get("_tempTheme")) { + } + + $theme = null; + if (Session::i()->get("_tempTheme")) { $theme = Themepacks::i()[Session::i()->get("_tempTheme", "ovk")]; - Session::i()->set("_tempTheme", NULL); - } else if(Session::i()->get("_sessionTheme")) { + Session::i()->set("_tempTheme", null); + } elseif (Session::i()->get("_sessionTheme")) { $theme = Themepacks::i()[Session::i()->get("_sessionTheme", "ovk")]; - } else if($this->requestParam("themePreview")) { + } elseif ($this->requestParam("themePreview")) { $theme = Themepacks::i()[$this->requestParam("themePreview")]; - } else if($this->user !== NULL && $this->user->identity !== NULL && $this->user->identity->getTheme()) { + } elseif ($this->user !== null && $this->user->identity !== null && $this->user->identity->getTheme()) { $theme = $this->user->identity->getTheme(); } - + $this->template->theme = $theme; - if(!is_null($theme) && $theme->overridesTemplates()) + if (!is_null($theme) && $theme->overridesTemplates()) { $this->template->_templatePath = $theme->getBaseDir() . "/tpl"; - - if(!is_null(Session::i()->get("_error"))) { + } + + if (!is_null(Session::i()->get("_error"))) { $this->template->flashMessage = json_decode(Session::i()->get("_error")); - Session::i()->set("_error", NULL); + Session::i()->set("_error", null); } } @@ -346,32 +359,35 @@ abstract class OpenVKPresenter extends SimplePresenter exit($payload); } - protected function isOldThing($whichbrowser) { - if($whichbrowser->isOs('Series60') || - $whichbrowser->isOs('Series40') || - $whichbrowser->isOs('Series80') || - $whichbrowser->isOs('Windows CE') || - $whichbrowser->isOs('Windows Mobile') || - $whichbrowser->isOs('Nokia Asha Platform') || - $whichbrowser->isOs('UIQ') || + protected function isOldThing($whichbrowser) + { + if ($whichbrowser->isOs('Series60') || + $whichbrowser->isOs('Series40') || + $whichbrowser->isOs('Series80') || + $whichbrowser->isOs('Windows CE') || + $whichbrowser->isOs('Windows Mobile') || + $whichbrowser->isOs('Nokia Asha Platform') || + $whichbrowser->isOs('UIQ') || $whichbrowser->isEngine('NetFront') || // PSP and other japanese portable systems - $whichbrowser->isOs('Android') || + $whichbrowser->isOs('Android') || $whichbrowser->isOs('iOS') || $whichbrowser->isBrowser('Internet Explorer', '<=', '8')) { // yeah, it's old, but ios and android are? - if($whichbrowser->isOs('iOS') && $whichbrowser->isOs('iOS', '<=', '9')) + if ($whichbrowser->isOs('iOS') && $whichbrowser->isOs('iOS', '<=', '9')) { return true; - elseif($whichbrowser->isOs('iOS') && $whichbrowser->isOs('iOS', '>', '9')) + } elseif ($whichbrowser->isOs('iOS') && $whichbrowser->isOs('iOS', '>', '9')) { return false; - - if($whichbrowser->isOs('Android') && $whichbrowser->isOs('Android', '<=', '5')) + } + + if ($whichbrowser->isOs('Android') && $whichbrowser->isOs('Android', '<=', '5')) { return true; - elseif($whichbrowser->isOs('Android') && $whichbrowser->isOs('Android', '>', '5')) + } elseif ($whichbrowser->isOs('Android') && $whichbrowser->isOs('Android', '>', '5')) { return false; + } return true; } else { return false; } } -} +} diff --git a/Web/Presenters/PhotosPresenter.php b/Web/Presenters/PhotosPresenter.php index 029d2aac..ebff8f7e 100644 --- a/Web/Presenters/PhotosPresenter.php +++ b/Web/Presenters/PhotosPresenter.php @@ -1,5 +1,9 @@ -users = $users; $this->photos = $photos; $this->albums = $albums; - + parent::__construct(); } - - function renderAlbumList(int $owner): void - { - if($owner > 0) { - $user = $this->users->get($owner); - if(!$user) $this->notFound(); - if (!$user->getPrivacyPermission('photos.read', $this->user->identity ?? NULL)) - $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); - $this->template->albums = $this->albums->getUserAlbums($user, (int)($this->queryParam("p") ?? 1)); + public function renderAlbumList(int $owner): void + { + if ($owner > 0) { + $user = $this->users->get($owner); + if (!$user) { + $this->notFound(); + } + if (!$user->getPrivacyPermission('photos.read', $this->user->identity ?? null)) { + $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); + } + + $this->template->albums = $this->albums->getUserAlbums($user, (int) ($this->queryParam("p") ?? 1)); $this->template->count = $this->albums->getUserAlbumsCount($user); $this->template->owner = $user; $this->template->canEdit = false; - if(!is_null($this->user)) + if (!is_null($this->user)) { $this->template->canEdit = $this->user->id === $user->getId(); + } } else { - $club = (new Clubs)->get(abs($owner)); - if(!$club) $this->notFound(); - $this->template->albums = $this->albums->getClubAlbums($club, (int)($this->queryParam("p") ?? 1)); + $club = (new Clubs())->get(abs($owner)); + if (!$club) { + $this->notFound(); + } + $this->template->albums = $this->albums->getClubAlbums($club, (int) ($this->queryParam("p") ?? 1)); $this->template->count = $this->albums->getClubAlbumsCount($club); $this->template->owner = $club; $this->template->canEdit = false; - if(!is_null($this->user)) + if (!is_null($this->user)) { $this->template->canEdit = $club->canBeModifiedBy($this->user->identity); + } } - + $this->template->paginatorConf = (object) [ "count" => $this->template->count, - "page" => (int)($this->queryParam("p") ?? 1), - "amount" => NULL, + "page" => (int) ($this->queryParam("p") ?? 1), + "amount" => null, "perPage" => OPENVK_DEFAULT_PER_PAGE, ]; } - - function renderCreateAlbum(): void + + public function renderCreateAlbum(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - - if(!is_null($gpid = $this->queryParam("gpid"))) { - $club = (new Clubs)->get((int) $gpid); - if(!$club->canBeModifiedBy($this->user->identity)) + + if (!is_null($gpid = $this->queryParam("gpid"))) { + $club = (new Clubs())->get((int) $gpid); + if (!$club->canBeModifiedBy($this->user->identity)) { $this->notFound(); - + } + $this->template->club = $club; } - - if($_SERVER["REQUEST_METHOD"] === "POST") { - if(empty($this->postParam("name")) || mb_strlen(trim($this->postParam("name"))) === 0) - $this->flashFail("err", tr("error"), tr("error_segmentation")); - else if(strlen($this->postParam("name")) > 36) - $this->flashFail("err", tr("error"), tr("error_data_too_big", "name", 36, "bytes")); - $album = new Album; + if ($_SERVER["REQUEST_METHOD"] === "POST") { + if (empty($this->postParam("name")) || mb_strlen(trim($this->postParam("name"))) === 0) { + $this->flashFail("err", tr("error"), tr("error_segmentation")); + } elseif (strlen($this->postParam("name")) > 36) { + $this->flashFail("err", tr("error"), tr("error_data_too_big", "name", 36, "bytes")); + } + + $album = new Album(); $album->setOwner(isset($club) ? $club->getId() * -1 : $this->user->id); $album->setName($this->postParam("name")); $album->setDescription($this->postParam("desc")); $album->setCreated(time()); $album->save(); - - if(isset($club)) + + if (isset($club)) { $this->redirect("/album-" . $album->getOwner()->getId() . "_" . $album->getId()); - else + } else { $this->redirect("/album" . $album->getOwner()->getId() . "_" . $album->getId()); + } } } - - function renderEditAlbum(int $owner, int $id): void + + public function renderEditAlbum(int $owner, int $id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - + $album = $this->albums->get($id); - if(!$album) $this->notFound(); - if($album->getPrettyId() !== $owner . "_" . $id || $album->isDeleted()) $this->notFound(); - if(is_null($this->user) || !$album->canBeModifiedBy($this->user->identity) || $album->isDeleted()) + if (!$album) { + $this->notFound(); + } + if ($album->getPrettyId() !== $owner . "_" . $id || $album->isDeleted()) { + $this->notFound(); + } + if (is_null($this->user) || !$album->canBeModifiedBy($this->user->identity) || $album->isDeleted()) { $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied")); + } $this->template->album = $album; - - if($_SERVER["REQUEST_METHOD"] === "POST") { - if(strlen($this->postParam("name")) > 36) + + if ($_SERVER["REQUEST_METHOD"] === "POST") { + if (strlen($this->postParam("name")) > 36) { $this->flashFail("err", tr("error"), tr("error_data_too_big", "name", 36, "bytes")); - + } + $album->setName((empty($this->postParam("name")) || mb_strlen(trim($this->postParam("name"))) === 0) ? $album->getName() : $this->postParam("name")); - $album->setDescription(empty($this->postParam("desc")) ? NULL : $this->postParam("desc")); + $album->setDescription(empty($this->postParam("desc")) ? null : $this->postParam("desc")); $album->setEdited(time()); $album->save(); - + $this->flash("succ", tr("changes_saved"), tr("new_data_accepted")); } } - - function renderDeleteAlbum(int $owner, int $id): void + + public function renderDeleteAlbum(int $owner, int $id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); $this->assertNoCSRF(); - + $album = $this->albums->get($id); - if(!$album) $this->notFound(); - if($album->getPrettyId() !== $owner . "_" . $id || $album->isDeleted()) $this->notFound(); - if(is_null($this->user) || !$album->canBeModifiedBy($this->user->identity)) + if (!$album) { + $this->notFound(); + } + if ($album->getPrettyId() !== $owner . "_" . $id || $album->isDeleted()) { + $this->notFound(); + } + if (is_null($this->user) || !$album->canBeModifiedBy($this->user->identity)) { $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied")); - + } + $name = $album->getName(); $owner = $album->getOwner(); $album->delete(); @@ -130,134 +155,154 @@ final class PhotosPresenter extends OpenVKPresenter $this->flash("succ", tr("album_is_deleted"), tr("album_x_is_deleted", $name)); $this->redirect("/albums" . ($owner instanceof Club ? "-" : "") . $owner->getId()); } - - function renderAlbum(int $owner, int $id): void + + public function renderAlbum(int $owner, int $id): void { $album = $this->albums->get($id); - if(!$album) $this->notFound(); - if($album->getPrettyId() !== $owner . "_" . $id || $album->isDeleted()) + if (!$album) { + $this->notFound(); + } + if ($album->getPrettyId() !== $owner . "_" . $id || $album->isDeleted()) { $this->notFound(); - - if(!$album->canBeViewedBy($this->user->identity)) - $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); - - if($owner > 0 /* bc we currently don't have perms for clubs */) { - $ownerObject = (new Users)->get($owner); - if(!$ownerObject->getPrivacyPermission('photos.read', $this->user->identity ?? NULL)) - $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); } - - $this->template->album = $album; - $this->template->photos = iterator_to_array( $album->getPhotos( (int) ($this->queryParam("p") ?? 1), 20) ); - $this->template->paginatorConf = (object) [ - "count" => $album->getPhotosCount(), - "page" => (int)($this->queryParam("p") ?? 1), - "amount" => sizeof($this->template->photos), - "perPage" => 20, - "atBottom" => true - ]; - } - - function renderPhoto(int $ownerId, int $photoId): void - { - $photo = $this->photos->getByOwnerAndVID($ownerId, $photoId); - if(!$photo || $photo->isDeleted()) $this->notFound(); - - if(!$photo->canBeViewedBy($this->user->identity)) - $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); - if(!is_null($this->queryParam("from"))) { - if(preg_match("%^album([0-9]++)$%", $this->queryParam("from"), $matches) === 1) { - $album = $this->albums->get((int) $matches[1]); - if($album) - if($album->hasPhoto($photo) && !$album->isDeleted()) - $this->template->album = $album; + if (!$album->canBeViewedBy($this->user->identity)) { + $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); + } + + if ($owner > 0 /* bc we currently don't have perms for clubs */) { + $ownerObject = (new Users())->get($owner); + if (!$ownerObject->getPrivacyPermission('photos.read', $this->user->identity ?? null)) { + $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); } } - + + $this->template->album = $album; + $this->template->photos = iterator_to_array($album->getPhotos((int) ($this->queryParam("p") ?? 1), 20)); + $this->template->paginatorConf = (object) [ + "count" => $album->getPhotosCount(), + "page" => (int) ($this->queryParam("p") ?? 1), + "amount" => sizeof($this->template->photos), + "perPage" => 20, + "atBottom" => true, + ]; + } + + public function renderPhoto(int $ownerId, int $photoId): void + { + $photo = $this->photos->getByOwnerAndVID($ownerId, $photoId); + if (!$photo || $photo->isDeleted()) { + $this->notFound(); + } + + if (!$photo->canBeViewedBy($this->user->identity)) { + $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); + } + + if (!is_null($this->queryParam("from"))) { + if (preg_match("%^album([0-9]++)$%", $this->queryParam("from"), $matches) === 1) { + $album = $this->albums->get((int) $matches[1]); + if ($album) { + if ($album->hasPhoto($photo) && !$album->isDeleted()) { + $this->template->album = $album; + } + } + } + } + $this->template->photo = $photo; $this->template->cCount = $photo->getCommentsCount(); $this->template->cPage = (int) ($this->queryParam("p") ?? 1); $this->template->comments = iterator_to_array($photo->getComments($this->template->cPage)); $this->template->owner = $photo->getOwner(); } - - function renderAbsolutePhoto($id): void + + public function renderAbsolutePhoto($id): void { $id = (int) base_convert((string) $id, 32, 10); $photo = $this->photos->get($id); - if(!$photo || $photo->isDeleted()) + if (!$photo || $photo->isDeleted()) { $this->notFound(); - + } + $this->template->_template = "Photos/Photo.xml"; $this->renderPhoto($photo->getOwner(true)->getId(), $photo->getVirtualId()); } - - function renderThumbnail($id, $size): void + + public function renderThumbnail($id, $size): void { $photo = $this->photos->get($id); - if(!$photo || $photo->isDeleted()) + if (!$photo || $photo->isDeleted()) { $this->notFound(); - - if(!$photo->forceSize($size)) + } + + if (!$photo->forceSize($size)) { chandler_http_panic(588, "Gone", "This thumbnail cannot be generated due to server misconfiguration"); - + } + $this->redirect($photo->getURLBySizeId($size), 8); } - - function renderEditPhoto(int $ownerId, int $photoId): void + + public function renderEditPhoto(int $ownerId, int $photoId): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - + $photo = $this->photos->getByOwnerAndVID($ownerId, $photoId); - if(!$photo) $this->notFound(); - if(is_null($this->user) || $this->user->id != $ownerId) + if (!$photo) { + $this->notFound(); + } + if (is_null($this->user) || $this->user->id != $ownerId) { $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied")); - - if($_SERVER["REQUEST_METHOD"] === "POST") { - $photo->setDescription(empty($this->postParam("desc")) ? NULL : $this->postParam("desc")); + } + + if ($_SERVER["REQUEST_METHOD"] === "POST") { + $photo->setDescription(empty($this->postParam("desc")) ? null : $this->postParam("desc")); $photo->save(); - + $this->flash("succ", tr("changes_saved"), tr("new_description_will_appear")); $this->redirect("/photo" . $photo->getPrettyId()); - } - + } + $this->template->photo = $photo; } - - function renderUploadPhoto(): void + + public function renderUploadPhoto(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(true); - if(is_null($this->queryParam("album"))) { + if (is_null($this->queryParam("album"))) { $album = $this->albums->getUserWallAlbum($this->user->identity); } else { [$owner, $id] = explode("_", $this->queryParam("album")); $album = $this->albums->get((int) $id); } - if(!$album) + if (!$album) { $this->flashFail("err", tr("error"), tr("error_adding_to_deleted"), 500, true); + } # Для быстрой загрузки фоток из пикера фотографий нужен альбом, но юзер не может загружать фото # в системные альбомы, так что так. - if(is_null($this->user) || !is_null($this->queryParam("album")) && !$album->canBeModifiedBy($this->user->identity)) + if (is_null($this->user) || !is_null($this->queryParam("album")) && !$album->canBeModifiedBy($this->user->identity)) { $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied"), 500, true); - - if($_SERVER["REQUEST_METHOD"] === "POST") { - if($this->queryParam("act") == "finish") { + } + + if ($_SERVER["REQUEST_METHOD"] === "POST") { + if ($this->queryParam("act") == "finish") { $result = json_decode($this->postParam("photos"), true); - - foreach($result as $photoId => $description) { + + foreach ($result as $photoId => $description) { $phot = $this->photos->get($photoId); - if(!$phot || $phot->isDeleted() || $phot->getOwner()->getId() != $this->user->id) + if (!$phot || $phot->isDeleted() || $phot->getOwner()->getId() != $this->user->id) { continue; - - if(iconv_strlen($description) > 255) + } + + if (iconv_strlen($description) > 255) { $this->flashFail("err", tr("error"), tr("description_too_long"), 500, true); + } $phot->setDescription($description); $phot->save(); @@ -266,23 +311,25 @@ final class PhotosPresenter extends OpenVKPresenter } $this->returnJson(["success" => true, - "album" => $album->getId(), - "owner" => $album->getOwner() instanceof User ? $album->getOwner()->getId() : $album->getOwner()->getId() * -1]); + "album" => $album->getId(), + "owner" => $album->getOwner() instanceof User ? $album->getOwner()->getId() : $album->getOwner()->getId() * -1]); } - if(!isset($_FILES)) + if (!isset($_FILES)) { $this->flashFail("err", tr("no_photo"), tr("select_file"), 500, true); - - $photos = []; - if((int)$this->postParam("count") > 10) - $this->flashFail("err", tr("no_photo"), "ты еблан", 500, true); + } - for($i = 0; $i < $this->postParam("count"); $i++) { + $photos = []; + if ((int) $this->postParam("count") > 10) { + $this->flashFail("err", tr("no_photo"), "ты еблан", 500, true); + } + + for ($i = 0; $i < $this->postParam("count"); $i++) { try { - $photo = new Photo; + $photo = new Photo(); $photo->setOwner($this->user->id); $photo->setDescription(""); - $photo->setFile($_FILES["photo_".$i]); + $photo->setFile($_FILES["photo_" . $i]); $photo->setCreated(time()); $photo->save(); @@ -294,7 +341,7 @@ final class PhotosPresenter extends OpenVKPresenter "link" => $photo->getURL(), "pretty_id" => $photo->getPrettyId(), ]; - } catch(ISE $ex) { + } catch (ISE $ex) { $name = $album->getName(); $this->flashFail("err", "Неизвестная ошибка", "Не удалось сохранить фотографию в $name.", 500, true); } @@ -310,75 +357,87 @@ final class PhotosPresenter extends OpenVKPresenter $this->template->album = $album; } } - - function renderUnlinkPhoto(int $owner, int $albumId, int $photoId): void + + public function renderUnlinkPhoto(int $owner, int $albumId, int $photoId): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - + $album = $this->albums->get($albumId); $photo = $this->photos->get($photoId); - if(!$album || !$photo) $this->notFound(); - if(!$album->hasPhoto($photo)) $this->notFound(); - if(is_null($this->user) || !$album->canBeModifiedBy($this->user->identity)) + if (!$album || !$photo) { + $this->notFound(); + } + if (!$album->hasPhoto($photo)) { + $this->notFound(); + } + if (is_null($this->user) || !$album->canBeModifiedBy($this->user->identity)) { $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied")); - - if($_SERVER["REQUEST_METHOD"] === "POST") { + } + + if ($_SERVER["REQUEST_METHOD"] === "POST") { $this->assertNoCSRF(); $album->removePhoto($photo); $album->setEdited(time()); $album->save(); - + $this->flash("succ", tr("photo_is_deleted"), tr("photo_is_deleted_desc")); $this->redirect("/album" . $album->getPrettyId()); } } - - function renderDeletePhoto(int $ownerId, int $photoId): void + + public function renderDeletePhoto(int $ownerId, int $photoId): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction($_SERVER["REQUEST_METHOD"] === "POST"); $this->assertNoCSRF(); - - $photo = $this->photos->getByOwnerAndVID($ownerId, $photoId); - if(!$photo) $this->notFound(); - if(is_null($this->user) || $this->user->id != $ownerId) - $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied")); - if(!is_null($album = $photo->getAlbum())) + $photo = $this->photos->getByOwnerAndVID($ownerId, $photoId); + if (!$photo) { + $this->notFound(); + } + if (is_null($this->user) || $this->user->id != $ownerId) { + $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied")); + } + + if (!is_null($album = $photo->getAlbum())) { $redirect = $album->getOwner() instanceof User ? "/id0" : "/club" . $ownerId; - else + } else { $redirect = "/id0"; + } $photo->isolate(); $photo->delete(); - - if($_SERVER["REQUEST_METHOD"] === "POST") + + if ($_SERVER["REQUEST_METHOD"] === "POST") { $this->returnJson(["success" => true]); + } $this->flash("succ", tr("photo_is_deleted"), tr("photo_is_deleted_desc")); $this->redirect($redirect); } - function renderLike(int $wall, int $post_id): void + public function renderLike(int $wall, int $post_id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); $this->assertNoCSRF(); - - $photo = $this->photos->getByOwnerAndVID($wall, $post_id); - if(!$photo || $photo->isDeleted() || !$photo->canBeViewedBy($this->user->identity)) $this->notFound(); - if(!is_null($this->user)) { + $photo = $this->photos->getByOwnerAndVID($wall, $post_id); + if (!$photo || $photo->isDeleted() || !$photo->canBeViewedBy($this->user->identity)) { + $this->notFound(); + } + + if (!is_null($this->user)) { $photo->toggleLike($this->user->identity); } - if($_SERVER["REQUEST_METHOD"] === "POST") { + if ($_SERVER["REQUEST_METHOD"] === "POST") { $this->returnJson([ 'success' => true, ]); } - + $this->redirect("$_SERVER[HTTP_REFERER]"); } } diff --git a/Web/Presenters/PollPresenter.php b/Web/Presenters/PollPresenter.php index 9c75e3bf..95a32d2c 100644 --- a/Web/Presenters/PollPresenter.php +++ b/Web/Presenters/PollPresenter.php @@ -1,25 +1,30 @@ -polls = $polls; - + parent::__construct(); } - - function renderView(int $id): void + + public function renderView(int $id): void { $poll = $this->polls->get($id); - if(!$poll) + if (!$poll) { $this->notFound(); - + } + $this->template->id = $poll->getId(); $this->template->title = $poll->getTitle(); $this->template->isAnon = $poll->isAnonymous(); @@ -29,41 +34,44 @@ final class PollPresenter extends OpenVKPresenter $this->template->votes = $poll->getVoterCount(); $this->template->meta = $poll->getMetaDescription(); $this->template->ended = $ended = $poll->hasEnded(); - if((is_null($this->user) || $poll->canVote($this->user->identity)) && !$ended) { + if ((is_null($this->user) || $poll->canVote($this->user->identity)) && !$ended) { $this->template->options = $poll->getOptions(); - + $this->template->_template = "Poll/Poll.xml"; return; } - - if(is_null($this->user)) { + + if (is_null($this->user)) { $this->template->voted = false; $this->template->results = $poll->getResults(); } else { $this->template->voted = $poll->hasVoted($this->user->identity); $this->template->results = $poll->getResults($this->user->identity); } - + $this->template->_template = "Poll/PollResults.xml"; } - - function renderVoters(int $pollId): void + + public function renderVoters(int $pollId): void { $poll = $this->polls->get($pollId); - if(!$poll) + if (!$poll) { $this->notFound(); - - if($poll->isAnonymous()) + } + + if ($poll->isAnonymous()) { $this->flashFail("err", tr("forbidden"), tr("poll_err_anonymous")); - + } + $options = $poll->getOptions(); $option = (int) base_convert($this->queryParam("option"), 32, 10); - if(!in_array($option, array_keys($options))) + if (!in_array($option, array_keys($options))) { $this->notFound(); - + } + $page = (int) ($this->queryParam("p") ?? 1); $voters = $poll->getVoters($option, $page); - + $this->template->pollId = $pollId; $this->template->options = $options; $this->template->option = [$option, $options[$option]]; @@ -72,4 +80,4 @@ final class PollPresenter extends OpenVKPresenter $this->template->count = $poll->getVoterCount($option); $this->template->page = $page; } -} \ No newline at end of file +} diff --git a/Web/Presenters/ReportPresenter.php b/Web/Presenters/ReportPresenter.php index ae9a6e75..f58eaa5c 100644 --- a/Web/Presenters/ReportPresenter.php +++ b/Web/Presenters/ReportPresenter.php @@ -1,5 +1,9 @@ -reports = $reports; - + parent::__construct(); } - - function renderList(): void + + public function renderList(): void { $this->assertUserLoggedIn(); $this->assertPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0); - if ($_SERVER["REQUEST_METHOD"] === "POST") + if ($_SERVER["REQUEST_METHOD"] === "POST") { $this->assertNoCSRF(); + } - $act = in_array($this->queryParam("act"), ["post", "photo", "video", "group", "comment", "note", "app", "user", "audio", "doc"]) ? $this->queryParam("act") : NULL; + $act = in_array($this->queryParam("act"), ["post", "photo", "video", "group", "comment", "note", "app", "user", "audio", "doc"]) ? $this->queryParam("act") : null; if (!$this->queryParam("orig")) { - $this->template->reports = $this->reports->getReports(0, (int)($this->queryParam("p") ?? 1), $act, $_SERVER["REQUEST_METHOD"] !== "POST"); + $this->template->reports = $this->reports->getReports(0, (int) ($this->queryParam("p") ?? 1), $act, $_SERVER["REQUEST_METHOD"] !== "POST"); $this->template->count = $this->reports->getReportsCount(); } else { $orig = $this->reports->get((int) $this->queryParam("orig")); - if (!$orig) $this->redirect("/scumfeed"); + if (!$orig) { + $this->redirect("/scumfeed"); + } $this->template->reports = $orig->getDuplicates(); $this->template->count = $orig->getDuplicatesCount(); @@ -39,7 +46,7 @@ final class ReportPresenter extends OpenVKPresenter $this->template->paginatorConf = (object) [ "count" => $this->template->count, "page" => $this->queryParam("p") ?? 1, - "amount" => NULL, + "amount" => null, "perPage" => 15, ]; $this->template->mode = $act ?? "all"; @@ -54,13 +61,13 @@ final class ReportPresenter extends OpenVKPresenter "id" => $report->getReportAuthor()->getId(), "url" => $report->getReportAuthor()->getURL(), "name" => $report->getReportAuthor()->getCanonicalName(), - "is_female" => $report->getReportAuthor()->isFemale() + "is_female" => $report->getReportAuthor()->isFemale(), ], "content" => [ "name" => $report->getContentName(), "type" => $report->getContentType(), "id" => $report->getContentId(), - "url" => $report->getContentType() === "user" ? (new Users)->get((int) $report->getContentId())->getURL() : NULL + "url" => $report->getContentType() === "user" ? (new Users())->get((int) $report->getContentId())->getURL() : null, ], "duplicates" => $report->getDuplicatesCount(), ]; @@ -68,34 +75,37 @@ final class ReportPresenter extends OpenVKPresenter $this->returnJson(["reports" => $reports]); } } - - function renderView(int $id): void + + public function renderView(int $id): void { $this->assertUserLoggedIn(); $this->assertPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0); $report = $this->reports->get($id); - if(!$report || $report->isDeleted()) + if (!$report || $report->isDeleted()) { $this->notFound(); - + } + $this->template->report = $report; $this->template->disable_ajax = 1; } - - function renderCreate(int $id): void + + public function renderCreate(int $id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - if(!$id) + if (!$id) { exit(json_encode([ "error" => tr("error_segmentation") ])); - - if ($this->queryParam("type") === "user" && $id === $this->user->id) - exit(json_encode([ "error" => "You can't report yourself" ])); + } - if(in_array($this->queryParam("type"), ["post", "photo", "video", "group", "comment", "note", "app", "user", "audio", "doc"])) { - if (count(iterator_to_array($this->reports->getDuplicates($this->queryParam("type"), $id, NULL, $this->user->id))) <= 0) { - $report = new Report; + if ($this->queryParam("type") === "user" && $id === $this->user->id) { + exit(json_encode([ "error" => "You can't report yourself" ])); + } + + if (in_array($this->queryParam("type"), ["post", "photo", "video", "group", "comment", "note", "app", "user", "audio", "doc"])) { + if (count(iterator_to_array($this->reports->getDuplicates($this->queryParam("type"), $id, null, $this->user->id))) <= 0) { + $report = new Report(); $report->setUser_id($this->user->id); $report->setTarget_id($id); $report->setType($this->queryParam("type")); @@ -103,42 +113,46 @@ final class ReportPresenter extends OpenVKPresenter $report->setCreated(time()); $report->save(); } - + exit(json_encode([ "reason" => $this->queryParam("reason") ])); } else { exit(json_encode([ "error" => "Unable to submit a report on this content type" ])); } } - - function renderAction(int $id): void + + public function renderAction(int $id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); $this->assertPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0); $report = $this->reports->get($id); - if(!$report || $report->isDeleted()) $this->notFound(); + if (!$report || $report->isDeleted()) { + $this->notFound(); + } if ($this->postParam("ban")) { $report->deleteContent(); $report->banUser($this->user->identity->getId()); $this->flash("suc", tr("death"), tr("user_successfully_banned")); - } else if ($this->postParam("delete")) { + } elseif ($this->postParam("delete")) { $report->deleteContent(); $this->flash("suc", tr("nehay"), tr("content_is_deleted")); - } else if ($this->postParam("ignore")) { + } elseif ($this->postParam("ignore")) { $report->delete(); $this->flash("suc", tr("nehay"), tr("report_is_ignored")); - } else if ($this->postParam("banClubOwner") || $this->postParam("banClub")) { - if ($report->getContentType() !== "group") + } elseif ($this->postParam("banClubOwner") || $this->postParam("banClub")) { + if ($report->getContentType() !== "group") { $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied")); + } $club = $report->getContentObject(); - if (!$club || $club->isBanned()) + if (!$club || $club->isBanned()) { $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied")); + } if ($this->postParam("banClubOwner")) { $club->getOwner()->ban("**content-" . $report->getContentType() . "-" . $report->getContentId() . "**", false, $club->getOwner()->getNewBanTime(), $this->user->identity->getId()); diff --git a/Web/Presenters/SearchPresenter.php b/Web/Presenters/SearchPresenter.php index 6ab03415..102a6435 100644 --- a/Web/Presenters/SearchPresenter.php +++ b/Web/Presenters/SearchPresenter.php @@ -1,5 +1,9 @@ -users = new Users; - $this->clubs = new Clubs; - $this->posts = new Posts; - $this->videos = new Videos; - $this->apps = new Applications; - $this->audios = new Audios; - $this->documents = new Documents; - + $this->users = new Users(); + $this->clubs = new Clubs(); + $this->posts = new Posts(); + $this->videos = new Videos(); + $this->apps = new Applications(); + $this->audios = new Audios(); + $this->documents = new Documents(); + parent::__construct(); } - - function renderIndex(): void + + public function renderIndex(): void { $this->assertUserLoggedIn(); @@ -40,51 +44,60 @@ final class SearchPresenter extends OpenVKPresenter # https://youtu.be/pSAWM5YuXx8 # https://youtu.be/FfNZRhIn2Vk - $repos = [ - "groups" => "clubs", + $repos = [ + "groups" => "clubs", "users" => "users", "posts" => "posts", "videos" => "videos", "audios" => "audios", "apps" => "apps", "audios_playlists" => "audios", - "docs" => "documents" + "docs" => "documents", ]; $parameters = [ "ignore_private" => true, ]; - foreach($_REQUEST as $param_name => $param_value) { - if(is_null($param_value)) continue; - - switch($param_name) { + foreach ($_REQUEST as $param_name => $param_value) { + if (is_null($param_value)) { + continue; + } + + switch ($param_name) { default: $parameters[$param_name] = $param_value; break; case 'marital_status': case 'polit_views': - if((int) $param_value == 0) continue; + if ((int) $param_value == 0) { + continue; + } $parameters[$param_name] = $param_value; break; case 'is_online': - if((int) $param_value == 1) + if ((int) $param_value == 1) { $parameters['is_online'] = 1; - + } + break; case 'only_performers': - if((int) $param_value == 1 || $param_value == 'on') + if ((int) $param_value == 1 || $param_value == 'on') { $parameters['only_performers'] = true; + } break; case 'with_lyrics': - if($param_value == 'on' || $param_value == '1') + if ($param_value == 'on' || $param_value == '1') { $parameters['with_lyrics'] = true; + } break; - # дай бог работал этот case + # дай бог работал этот case case 'from_me': - if((int) $param_value != 1) continue; + if ((int) $param_value != 1) { + continue; + } $parameters['from_me'] = $this->user->id; break; @@ -92,9 +105,9 @@ final class SearchPresenter extends OpenVKPresenter } $repo = $repos[$section] or $this->throwError(400, "Bad Request", "Invalid search entity $section."); - - $results = NULL; - switch($section) { + + $results = null; + switch ($section) { default: $results = $this->{$repo}->find($query, $parameters, ['type' => $order, 'invert' => $invert]); break; @@ -102,10 +115,10 @@ final class SearchPresenter extends OpenVKPresenter $results = $this->{$repo}->findPlaylists($query, $parameters, ['type' => $order, 'invert' => $invert]); break; } - + $iterator = $results->page($page, OPENVK_DEFAULT_PER_PAGE); $count = $results->size(); - + $this->template->order = $order; $this->template->invert = $invert; $this->template->data = $this->template->iterator = iterator_to_array($iterator); diff --git a/Web/Presenters/SupportPresenter.php b/Web/Presenters/SupportPresenter.php index b834d712..2ab2de2b 100644 --- a/Web/Presenters/SupportPresenter.php +++ b/Web/Presenters/SupportPresenter.php @@ -1,5 +1,9 @@ -tickets = $tickets; $this->comments = $ticketComments; - + parent::__construct(); } - - function renderIndex(): void + + public function renderIndex(): void { $this->assertUserLoggedIn(); $this->template->mode = in_array($this->queryParam("act"), ["faq", "new", "list"]) ? $this->queryParam("act") : "faq"; - if($this->template->mode === "faq") { + if ($this->template->mode === "faq") { $lang = Session::i()->get("lang", "ru"); $base = OPENVK_ROOT . "/data/knowledgebase/faq"; - if(file_exists("$base.$lang.md")) + if (file_exists("$base.$lang.md")) { $file = "$base.$lang.md"; - else if(file_exists("$base.md")) + } elseif (file_exists("$base.md")) { $file = "$base.md"; - else - $file = NULL; + } else { + $file = null; + } - if(is_null($file)) { + if (is_null($file)) { $this->template->faq = []; } else { $lines = file($file); $faq = []; $index = 0; - foreach($lines as $line) { - if(strpos($line, "# ") === 0) + foreach ($lines as $line) { + if (strpos($line, "# ") === 0) { ++$index; + } $faq[$index][] = $line; } - $this->template->faq = array_map(function($section) { + $this->template->faq = array_map(function ($section) { $title = substr($section[0], 2); array_shift($section); return [ $title, - (new Parsedown())->text(implode("\n", $section)) + (new Parsedown())->text(implode("\n", $section)), ]; }, $faq); } } $this->template->count = $this->tickets->getTicketsCountByUserId($this->user->id); - if($this->template->mode === "list") { + if ($this->template->mode === "list") { $this->template->page = (int) ($this->queryParam("p") ?? 1); $this->template->tickets = iterator_to_array($this->tickets->getTicketsByUserId($this->user->id, $this->template->page)); } - if($this->template->mode === "new") + if ($this->template->mode === "new") { $this->template->banReason = $this->user->identity->getBanInSupportReason(); - - if($_SERVER["REQUEST_METHOD"] === "POST") { - if($this->user->identity->isBannedInSupport()) - $this->flashFail("err", tr("not_enough_permissions"), tr("not_enough_permissions_comment")); + } - if(!empty($this->postParam("name")) && !empty($this->postParam("text"))) { + if ($_SERVER["REQUEST_METHOD"] === "POST") { + if ($this->user->identity->isBannedInSupport()) { + $this->flashFail("err", tr("not_enough_permissions"), tr("not_enough_permissions_comment")); + } + + if (!empty($this->postParam("name")) && !empty($this->postParam("text"))) { $this->willExecuteWriteAction(); - $ticket = new Ticket; + $ticket = new Ticket(); $ticket->setType(0); $ticket->setUser_Id($this->user->id); $ticket->setName($this->postParam("name")); @@ -89,7 +97,7 @@ final class SupportPresenter extends OpenVKPresenter $ticket->save(); $helpdeskChat = OPENVK_ROOT_CONF["openvk"]["credentials"]["telegram"]["helpdeskChat"]; - if($helpdeskChat) { + if ($helpdeskChat) { $serverUrl = ovk_scheme(true) . $_SERVER["SERVER_NAME"]; $ticketText = ovk_proc_strtr($this->postParam("text"), 1500); $telegramText = "📬 Новый тикет!\n\n"; @@ -105,14 +113,14 @@ final class SupportPresenter extends OpenVKPresenter } } } - - function renderList(): void + + public function renderList(): void { $this->assertUserLoggedIn(); $this->assertPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0); - + $act = $this->queryParam("act") ?? "open"; - switch($act) { + switch ($act) { default: # NOTICE falling through case "open": @@ -124,87 +132,89 @@ final class SupportPresenter extends OpenVKPresenter case "closed": $state = 2; } - + $this->template->act = $act; $this->template->page = (int) ($this->queryParam("p") ?? 1); $this->template->count = $this->tickets->getTicketCount($state); $this->template->iterator = $this->tickets->getTickets($state, $this->template->page); } - - function renderView(int $id): void + + public function renderView(int $id): void { $this->assertUserLoggedIn(); $ticket = $this->tickets->get($id); $ticketComments = $this->comments->getCommentsById($id); - if(!$ticket || $ticket->isDeleted() != 0 || $ticket->getUserId() !== $this->user->id) { + if (!$ticket || $ticket->isDeleted() != 0 || $ticket->getUserId() !== $this->user->id) { $this->notFound(); } else { - $this->template->ticket = $ticket; - $this->template->comments = $ticketComments; - $this->template->id = $id; + $this->template->ticket = $ticket; + $this->template->comments = $ticketComments; + $this->template->id = $id; } } - - function renderDelete(int $id): void + + public function renderDelete(int $id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - if(!empty($id)) { + if (!empty($id)) { $ticket = $this->tickets->get($id); - if(!$ticket || $ticket->isDeleted() != 0 || $ticket->getUserId() !== $this->user->id && !$this->hasPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0)) { + if (!$ticket || $ticket->isDeleted() != 0 || $ticket->getUserId() !== $this->user->id && !$this->hasPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0)) { $this->notFound(); } else { - if($ticket->getUserId() !== $this->user->id && $this->hasPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0)) + if ($ticket->getUserId() !== $this->user->id && $this->hasPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0)) { $_redirect = "/support/tickets"; - else + } else { $_redirect = "/support?act=list"; + } $ticket->delete(); $this->redirect($_redirect); } } } - - function renderMakeComment(int $id): void + + public function renderMakeComment(int $id): void { $ticket = $this->tickets->get($id); - - if($ticket->isDeleted() === 1 || $ticket->getType() === 2 || $ticket->getUserId() !== $this->user->id) { + + if ($ticket->isDeleted() === 1 || $ticket->getType() === 2 || $ticket->getUserId() !== $this->user->id) { header("HTTP/1.1 403 Forbidden"); header("Location: /support/view/" . $id); exit; } - - if($_SERVER["REQUEST_METHOD"] === "POST") { - if(!empty($this->postParam("text"))) { + + if ($_SERVER["REQUEST_METHOD"] === "POST") { + if (!empty($this->postParam("text"))) { $ticket->setType(0); $ticket->save(); $this->willExecuteWriteAction(); - - $comment = new TicketComment; + + $comment = new TicketComment(); $comment->setUser_id($this->user->id); $comment->setUser_type(0); $comment->setText($this->postParam("text")); $comment->setTicket_id($id); $comment->setCreated(time()); $comment->save(); - + $this->redirect("/support/view/" . $id); } else { $this->flashFail("err", tr("error"), tr("you_have_not_entered_text")); } } } - - function renderAnswerTicket(int $id): void + + public function renderAnswerTicket(int $id): void { $this->assertPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0); $ticket = $this->tickets->get($id); - if(!$ticket || $ticket->isDeleted() != 0) + if (!$ticket || $ticket->isDeleted() != 0) { $this->notFound(); + } $ticketComments = $this->comments->getCommentsById($id); $this->template->ticket = $ticket; @@ -212,78 +222,82 @@ final class SupportPresenter extends OpenVKPresenter $this->template->id = $id; $this->template->fastAnswers = OPENVK_ROOT_CONF["openvk"]["preferences"]["support"]["fastAnswers"]; } - - function renderAnswerTicketReply(int $id): void + + public function renderAnswerTicketReply(int $id): void { $this->assertPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0); - + $ticket = $this->tickets->get($id); - - if($_SERVER["REQUEST_METHOD"] === "POST") { + + if ($_SERVER["REQUEST_METHOD"] === "POST") { $this->willExecuteWriteAction(); - - if(!empty($this->postParam("text")) && !empty($this->postParam("status"))) { + + if (!empty($this->postParam("text")) && !empty($this->postParam("status"))) { $ticket->setType($this->postParam("status")); $ticket->save(); - $comment = new TicketComment; + $comment = new TicketComment(); $comment->setUser_id($this->user->id); $comment->setUser_type(1); $comment->setText($this->postParam("text")); $comment->setTicket_Id($id); $comment->setCreated(time()); $comment->save(); - } elseif(empty($this->postParam("text"))) { + } elseif (empty($this->postParam("text"))) { $ticket->setType($this->postParam("status")); $ticket->save(); } - + $this->flashFail("succ", tr("ticket_changed"), tr("ticket_changed_comment")); } } - - function renderKnowledgeBaseArticle(string $name): void + + public function renderKnowledgeBaseArticle(string $name): void { $lang = Session::i()->get("lang", "ru"); $base = OPENVK_ROOT . "/data/knowledgebase"; - if(file_exists("$base/$name.$lang.md")) + if (file_exists("$base/$name.$lang.md")) { $file = "$base/$name.$lang.md"; - else if(file_exists("$base/$name.md")) + } elseif (file_exists("$base/$name.md")) { $file = "$base/$name.md"; - else + } else { $this->notFound(); - + } + $lines = file($file); - if(!preg_match("%^OpenVK-KB-Heading: (.+)$%", $lines[0], $matches)) { + if (!preg_match("%^OpenVK-KB-Heading: (.+)$%", $lines[0], $matches)) { $heading = "Article $name"; } else { $heading = $matches[1]; array_shift($lines); } - + $content = implode($lines); - + $parser = new Parsedown(); $this->template->heading = $heading; $this->template->content = $parser->text($content); } - function renderDeleteComment(int $id): void + public function renderDeleteComment(int $id): void { $this->assertUserLoggedIn(); $this->assertNoCSRF(); $comment = $this->comments->get($id); - if(is_null($comment)) + if (is_null($comment)) { $this->notFound(); + } $ticket = $comment->getTicket(); - if($ticket->isDeleted()) + if ($ticket->isDeleted()) { $this->notFound(); + } - if(!($ticket->getUserId() === $this->user->id && $comment->getUType() === 0)) + if (!($ticket->getUserId() === $this->user->id && $comment->getUType() === 0)) { $this->assertPermission("openvk\Web\Models\Entities\TicketReply", "write", 0); + } $this->willExecuteWriteAction(); $comment->delete(); @@ -291,7 +305,7 @@ final class SupportPresenter extends OpenVKPresenter $this->flashFail("succ", tr("ticket_changed"), tr("ticket_changed_comment")); } - function renderRateAnswer(int $id, int $mark): void + public function renderRateAnswer(int $id, int $mark): void { $this->willExecuteWriteAction(); $this->assertUserLoggedIn(); @@ -299,11 +313,13 @@ final class SupportPresenter extends OpenVKPresenter $comment = $this->comments->get($id); - if($this->user->id !== $comment->getTicket()->getUser()->getId()) + if ($this->user->id !== $comment->getTicket()->getUser()->getId()) { exit(header("HTTP/1.1 403 Forbidden")); + } - if($mark !== 1 && $mark !== 2) + if ($mark !== 1 && $mark !== 2) { exit(header("HTTP/1.1 400 Bad Request")); + } $comment->setMark($mark); $comment->save(); @@ -311,93 +327,102 @@ final class SupportPresenter extends OpenVKPresenter exit(header("HTTP/1.1 200 OK")); } - function renderQuickBanInSupport(int $id): void + public function renderQuickBanInSupport(int $id): void { $this->assertPermission("openvk\Web\Models\Entities\TicketReply", "write", 0); $this->assertNoCSRF(); - $user = (new Users)->get($id); - if(!$user) + $user = (new Users())->get($id); + if (!$user) { exit(json_encode([ "error" => "User does not exist" ])); - + } + $user->setBlock_In_Support_Reason($this->queryParam("reason")); $user->save(); - if($this->queryParam("close_tickets")) - DatabaseConnection::i()->getConnection()->query("UPDATE tickets SET type = 2 WHERE user_id = ".$id); + if ($this->queryParam("close_tickets")) { + DatabaseConnection::i()->getConnection()->query("UPDATE tickets SET type = 2 WHERE user_id = " . $id); + } $this->returnJson([ "success" => true, "reason" => $this->queryParam("reason") ]); } - function renderQuickUnbanInSupport(int $id): void + public function renderQuickUnbanInSupport(int $id): void { $this->assertPermission("openvk\Web\Models\Entities\TicketReply", "write", 0); $this->assertNoCSRF(); - - $user = (new Users)->get($id); - if(!$user) + + $user = (new Users())->get($id); + if (!$user) { exit(json_encode([ "error" => "User does not exist" ])); - + } + $user->setBlock_In_Support_Reason(null); $user->save(); $this->returnJson([ "success" => true ]); } - function renderAgent(int $id): void + public function renderAgent(int $id): void { $this->assertPermission("openvk\Web\Models\Entities\TicketReply", "write", 0); - $support_names = new SupportAgents; + $support_names = new SupportAgents(); - if(!$support_names->isExists($id)) + if (!$support_names->isExists($id)) { $this->template->mode = "edit"; + } $this->template->agent_id = $id; $this->template->mode = in_array($this->queryParam("act"), ["info", "edit"]) ? $this->queryParam("act") : "info"; - $this->template->agent = $support_names->get($id) ?? NULL; + $this->template->agent = $support_names->get($id) ?? null; $this->template->counters = [ - "all" => (new TicketComments)->getCountByAgent($id), - "good" => (new TicketComments)->getCountByAgent($id, 1), - "bad" => (new TicketComments)->getCountByAgent($id, 2) + "all" => (new TicketComments())->getCountByAgent($id), + "good" => (new TicketComments())->getCountByAgent($id, 1), + "bad" => (new TicketComments())->getCountByAgent($id, 2), ]; - if($id != $this->user->identity->getId()) - if ($support_names->isExists($id)) + if ($id != $this->user->identity->getId()) { + if ($support_names->isExists($id)) { $this->template->mode = "info"; - else + } else { $this->redirect("/support/agent" . $this->user->identity->getId()); + } + } } - function renderEditAgent(int $id): void + public function renderEditAgent(int $id): void { $this->assertPermission("openvk\Web\Models\Entities\TicketReply", "write", 0); $this->assertNoCSRF(); - $support_names = new SupportAgents; + $support_names = new SupportAgents(); $agent = $support_names->get($id); - if($agent) - if($agent->getAgentId() != $this->user->identity->getId()) $this->flashFail("err", tr("error"), tr("forbidden")); + if ($agent) { + if ($agent->getAgentId() != $this->user->identity->getId()) { + $this->flashFail("err", tr("error"), tr("forbidden")); + } + } if ($support_names->isExists($id)) { $agent = $support_names->get($id); $agent->setName($this->postParam("name") ?? tr("helpdesk_agent")); - $agent->setNumerate((int) $this->postParam("number") ?? NULL); + $agent->setNumerate((int) $this->postParam("number") ?? null); $agent->setIcon($this->postParam("avatar")); $agent->save(); $this->flashFail("succ", tr("agent_profile_edited")); } else { - $agent = new SupportAgent; + $agent = new SupportAgent(); $agent->setAgent($this->user->identity->getId()); $agent->setName($this->postParam("name") ?? tr("helpdesk_agent")); - $agent->setNumerate((int) $this->postParam("number") ?? NULL); + $agent->setNumerate((int) $this->postParam("number") ?? null); $agent->setIcon($this->postParam("avatar")); $agent->save(); $this->flashFail("succ", tr("agent_profile_created_1"), tr("agent_profile_created_2")); } } - function renderCloseTicket(int $id): void + public function renderCloseTicket(int $id): void { $this->assertUserLoggedIn(); $this->assertNoCSRF(); @@ -405,7 +430,7 @@ final class SupportPresenter extends OpenVKPresenter $ticket = $this->tickets->get($id); - if($ticket->isDeleted() === 1 || $ticket->getType() === 2 || $ticket->getUserId() !== $this->user->id) { + if ($ticket->isDeleted() === 1 || $ticket->getType() === 2 || $ticket->getUserId() !== $this->user->id) { header("HTTP/1.1 403 Forbidden"); header("Location: /support/view/" . $id); exit; diff --git a/Web/Presenters/ThemepacksPresenter.php b/Web/Presenters/ThemepacksPresenter.php index 37ababc9..c9ba2bd7 100644 --- a/Web/Presenters/ThemepacksPresenter.php +++ b/Web/Presenters/ThemepacksPresenter.php @@ -1,32 +1,39 @@ -notFound(); - else + } else { $theme = Themepacks::i()[$themepack]; - - if($resClass === "resource") { + } + + if ($resClass === "resource") { $data = $theme->fetchStaticResource(chandler_escape_url($resource)); - } else if($resClass === "stylesheet") { - if($resource !== "styles.css") + } elseif ($resClass === "stylesheet") { + if ($resource !== "styles.css") { $this->notFound(); - else + } else { $data = $theme->fetchStyleSheet(); + } } else { $this->notFound(); } - - if(!$data) + + if (!$data) { $this->notFound(); - + } + header("Content-Type: " . system_extension_mime_type($resource) ?? "text/plain; charset=unknown-8bit"); header("Content-Size: " . strlen($data)); header("Cache-Control: public, no-transform, max-age=31536000"); diff --git a/Web/Presenters/TopicsPresenter.php b/Web/Presenters/TopicsPresenter.php index 92d67e84..dadbb300 100644 --- a/Web/Presenters/TopicsPresenter.php +++ b/Web/Presenters/TopicsPresenter.php @@ -1,5 +1,9 @@ -topics = $topics; $this->clubs = $clubs; - + parent::__construct(); } - function renderBoard(int $id): void + public function renderBoard(int $id): void { $this->assertUserLoggedIn(); $club = $this->clubs->get($id); - if(!$club) + if (!$club) { $this->notFound(); + } $this->template->club = $club; $page = (int) ($this->queryParam("p") ?? 1); $query = $this->queryParam("query"); - if($query) { + if ($query) { $results = $this->topics->find($club, $query); $this->template->topics = $results->page($page); $this->template->count = $results->size(); @@ -41,18 +46,19 @@ final class TopicsPresenter extends OpenVKPresenter $this->template->paginatorConf = (object) [ "count" => $this->template->count, "page" => $page, - "amount" => NULL, + "amount" => null, "perPage" => OPENVK_DEFAULT_PER_PAGE, ]; } - function renderTopic(int $clubId, int $topicId): void + public function renderTopic(int $clubId, int $topicId): void { $this->assertUserLoggedIn(); $topic = $this->topics->getTopicById($clubId, $topicId); - if(!$topic) + if (!$topic) { $this->notFound(); + } $this->template->topic = $topic; $this->template->club = $topic->getClub(); @@ -61,63 +67,69 @@ final class TopicsPresenter extends OpenVKPresenter $this->template->comments = iterator_to_array($topic->getComments($this->template->page)); } - function renderCreate(int $clubId): void + public function renderCreate(int $clubId): void { $this->assertUserLoggedIn(); $club = $this->clubs->get($clubId); - if(!$club) + if (!$club) { $this->notFound(); + } - if(!$club->isEveryoneCanCreateTopics() && !$club->canBeModifiedBy($this->user->identity)) + if (!$club->isEveryoneCanCreateTopics() && !$club->canBeModifiedBy($this->user->identity)) { $this->notFound(); + } - - if($_SERVER["REQUEST_METHOD"] === "POST") { + + if ($_SERVER["REQUEST_METHOD"] === "POST") { $this->willExecuteWriteAction(); $title = $this->postParam("title"); - if(!$title) + if (!$title) { $this->flashFail("err", tr("failed_to_create_topic"), tr("no_title_specified")); + } $flags = 0; - if($this->postParam("as_group") === "on" && $club->canBeModifiedBy($this->user->identity)) + if ($this->postParam("as_group") === "on" && $club->canBeModifiedBy($this->user->identity)) { $flags |= 0b10000000; + } - if($_FILES["_vid_attachment"] && OPENVK_ROOT_CONF['openvk']['preferences']['videos']['disableUploading']) + if ($_FILES["_vid_attachment"] && OPENVK_ROOT_CONF['openvk']['preferences']['videos']['disableUploading']) { $this->flashFail("err", tr("error"), "Video uploads are disabled by the system administrator."); + } - $topic = new Topic; + $topic = new Topic(); $topic->setGroup($club->getId()); $topic->setOwner($this->user->id); $topic->setTitle(ovk_proc_strtr($title, 127)); $topic->setCreated(time()); $topic->setFlags($flags); $topic->save(); - + # TODO move to trait try { - $photo = NULL; - $video = NULL; - if($_FILES["_pic_attachment"]["error"] === UPLOAD_ERR_OK) { - $album = NULL; - if($wall > 0 && $wall === $this->user->id) - $album = (new Albums)->getUserWallAlbum($wallOwner); - + $photo = null; + $video = null; + if ($_FILES["_pic_attachment"]["error"] === UPLOAD_ERR_OK) { + $album = null; + if ($wall > 0 && $wall === $this->user->id) { + $album = (new Albums())->getUserWallAlbum($wallOwner); + } + $photo = Photo::fastMake($this->user->id, $this->postParam("text"), $_FILES["_pic_attachment"], $album); } - - if($_FILES["_vid_attachment"]["error"] === UPLOAD_ERR_OK) { + + if ($_FILES["_vid_attachment"]["error"] === UPLOAD_ERR_OK) { $video = Video::fastMake($this->user->id, $_FILES["_vid_attachment"]["name"], $this->postParam("text"), $_FILES["_vid_attachment"]); } - } catch(ISE $ex) { + } catch (ISE $ex) { $this->flash("err", tr("error_when_publishing_comment"), tr("error_comment_file_too_big")); $this->redirect("/topic" . $topic->getPrettyId()); } - - if(!empty($this->postParam("text")) || $photo || $video) { + + if (!empty($this->postParam("text")) || $photo || $video) { try { - $comment = new Comment; + $comment = new Comment(); $comment->setOwner($this->user->id); $comment->setModel(get_class($topic)); $comment->setTarget($topic->getId()); @@ -129,12 +141,14 @@ final class TopicsPresenter extends OpenVKPresenter $this->flash("err", tr("error_when_publishing_comment"), tr("error_comment_too_big")); $this->redirect("/topic" . $topic->getPrettyId()); } - - if(!is_null($photo)) + + if (!is_null($photo)) { $comment->attach($photo); - - if(!is_null($video)) + } + + if (!is_null($video)) { $comment->attach($video); + } } $this->redirect("/topic" . $topic->getPrettyId()); @@ -144,32 +158,36 @@ final class TopicsPresenter extends OpenVKPresenter $this->template->graffiti = (bool) ovkGetQuirk("comments.allow-graffiti"); } - function renderEdit(int $clubId, int $topicId): void + public function renderEdit(int $clubId, int $topicId): void { $this->assertUserLoggedIn(); $topic = $this->topics->getTopicById($clubId, $topicId); - if(!$topic) + if (!$topic) { $this->notFound(); + } - if(!$topic->canBeModifiedBy($this->user->identity)) + if (!$topic->canBeModifiedBy($this->user->identity)) { $this->notFound(); + } - if($_SERVER["REQUEST_METHOD"] === "POST") { + if ($_SERVER["REQUEST_METHOD"] === "POST") { $this->willExecuteWriteAction(); $title = $this->postParam("title"); - if(!$title) + if (!$title) { $this->flashFail("err", tr("failed_to_change_topic"), tr("no_title_specified")); + } $topic->setTitle(ovk_proc_strtr($title, 127)); $topic->setClosed(empty($this->postParam("close")) ? 0 : 1); - if($topic->getClub()->canBeModifiedBy($this->user->identity)) + if ($topic->getClub()->canBeModifiedBy($this->user->identity)) { $topic->setPinned(empty($this->postParam("pin")) ? 0 : 1); + } $topic->save(); - + $this->flash("succ", tr("changes_saved"), tr("topic_changes_saved_comment")); $this->redirect("/topic" . $topic->getPrettyId()); } @@ -178,21 +196,23 @@ final class TopicsPresenter extends OpenVKPresenter $this->template->club = $topic->getClub(); } - function renderDelete(int $clubId, int $topicId): void + public function renderDelete(int $clubId, int $topicId): void { $this->assertUserLoggedIn(); $this->assertNoCSRF(); $topic = $this->topics->getTopicById($clubId, $topicId); - if(!$topic) + if (!$topic) { $this->notFound(); + } - if(!$topic->canBeModifiedBy($this->user->identity)) + if (!$topic->canBeModifiedBy($this->user->identity)) { $this->notFound(); + } $this->willExecuteWriteAction(); $topic->deleteTopic(); - + $this->redirect("/board" . $topic->getClub()->getId()); } } diff --git a/Web/Presenters/UnknownTextRouteStrategyPresenter.php b/Web/Presenters/UnknownTextRouteStrategyPresenter.php index 004da043..fe23986d 100644 --- a/Web/Presenters/UnknownTextRouteStrategyPresenter.php +++ b/Web/Presenters/UnknownTextRouteStrategyPresenter.php @@ -1,20 +1,26 @@ -= 2) { - $user = (new Users)->getByShortURL($data); - if($user) + if (strlen($data) >= 2) { + $user = (new Users())->getByShortURL($data); + if ($user) { $this->pass("openvk!User->view", $user->getId()); - $club = (new Clubs)->getByShortURL($data); - if($club) + } + $club = (new Clubs())->getByShortURL($data); + if ($club) { $this->pass("openvk!Group->view", "public", $club->getId()); + } } - + $this->notFound(); } } diff --git a/Web/Presenters/UserPresenter.php b/Web/Presenters/UserPresenter.php index 9d37458f..8770b4de 100644 --- a/Web/Presenters/UserPresenter.php +++ b/Web/Presenters/UserPresenter.php @@ -1,5 +1,9 @@ -users = $users; - + parent::__construct(); } - - function renderView(int $id): void + + public function renderView(int $id): void { $user = $this->users->get($id); - if(!$user || $user->isDeleted() || !$user->canBeViewedBy($this->user->identity)) { - if(!is_null($user) && $user->isDeactivated()) { + if (!$user || $user->isDeleted() || !$user->canBeViewedBy($this->user->identity)) { + if (!is_null($user) && $user->isDeactivated()) { $this->template->_template = "User/deactivated.xml"; - + $this->template->user = $user; - } else if(!is_null($user) && $this->user->identity && $this->user->identity->isBlacklistedBy($user)) { + } elseif (!is_null($user) && $this->user->identity && $this->user->identity->isBlacklistedBy($user)) { $this->template->_template = "User/blacklisted.xml"; $this->template->blacklist_status = $user->isBlacklistedBy($this->user->identity); $this->template->ignore_status = $user->isIgnoredBy($this->user->identity); $this->template->user = $user; - } else if(!is_null($user) && $user->isBlacklistedBy($this->user->identity)) { + } elseif (!is_null($user) && $user->isBlacklistedBy($this->user->identity)) { $this->template->_template = "User/blacklisted_pov.xml"; - + $this->template->ignore_status = $user->isIgnoredBy($this->user->identity); $this->template->user = $user; - } else if(!is_null($user) && !$user->canBeViewedBy($this->user->identity)) { + } elseif (!is_null($user) && !$user->canBeViewedBy($this->user->identity)) { $this->template->_template = "User/private.xml"; - + $this->template->user = $user; } else { $this->template->_template = "User/deleted.xml"; } } else { - $this->template->albums = (new Albums)->getUserAlbums($user); - $this->template->avatarAlbum = (new Albums)->getUserAvatarAlbum($user); - $this->template->albumsCount = (new Albums)->getUserAlbumsCount($user); - $this->template->videos = (new Videos)->getByUser($user, 1, 2); - $this->template->videosCount = (new Videos)->getUserVideosCount($user); - $this->template->notes = (new Notes)->getUserNotes($user, 1, 4); - $this->template->notesCount = (new Notes)->getUserNotesCount($user); - $this->template->audios = (new Audios)->getRandomThreeAudiosByEntityId($user->getId()); - $this->template->audiosCount = (new Audios)->getUserCollectionSize($user); + $this->template->albums = (new Albums())->getUserAlbums($user); + $this->template->avatarAlbum = (new Albums())->getUserAvatarAlbum($user); + $this->template->albumsCount = (new Albums())->getUserAlbumsCount($user); + $this->template->videos = (new Videos())->getByUser($user, 1, 2); + $this->template->videosCount = (new Videos())->getUserVideosCount($user); + $this->template->notes = (new Notes())->getUserNotes($user, 1, 4); + $this->template->notesCount = (new Notes())->getUserNotesCount($user); + $this->template->audios = (new Audios())->getRandomThreeAudiosByEntityId($user->getId()); + $this->template->audiosCount = (new Audios())->getUserCollectionSize($user); $this->template->audioStatus = $user->getCurrentAudioStatus(); $this->template->additionalFields = $user->getAdditionalFields(true); $this->template->user = $user; - if($id !== $this->user->id) { + if ($id !== $this->user->id) { $this->template->ignore_status = $user->isIgnoredBy($this->user->identity); $this->template->blacklist_status = $user->isBlacklistedBy($this->user->identity); } } } - - function renderFriends(int $id): void + + public function renderFriends(int $id): void { $this->assertUserLoggedIn(); - + $user = $this->users->get($id); - $page = abs((int)($this->queryParam("p") ?? 1)); - if(!$user) + $page = abs((int) ($this->queryParam("p") ?? 1)); + if (!$user) { $this->notFound(); - elseif (!$user->getPrivacyPermission('friends.read', $this->user->identity ?? NULL)) + } elseif (!$user->getPrivacyPermission('friends.read', $this->user->identity ?? null)) { $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); - else + } else { $this->template->user = $user; - + } + $this->template->mode = in_array($this->queryParam("act"), [ - "incoming", "outcoming", "friends" + "incoming", "outcoming", "friends", ]) ? $this->queryParam("act") : "friends"; $this->template->page = $page; - - if(!is_null($this->user)) { - if($this->template->mode !== "friends" && $this->user->id !== $id) { + + if (!is_null($this->user)) { + if ($this->template->mode !== "friends" && $this->user->id !== $id) { $name = $user->getFullName(); $this->flash("err", tr("error_access_denied_short"), tr("error_viewing_subs", $name)); - + $this->redirect($user->getURL()); } } } - - function renderGroups(int $id): void + + public function renderGroups(int $id): void { $this->assertUserLoggedIn(); - + $user = $this->users->get($id); - if(!$user) + if (!$user) { $this->notFound(); - elseif (!$user->getPrivacyPermission('groups.read', $this->user->identity ?? NULL)) + } elseif (!$user->getPrivacyPermission('groups.read', $this->user->identity ?? null)) { $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); - else { - if($this->queryParam("act") === "managed" && $this->user->id !== $user->getId()) + } else { + if ($this->queryParam("act") === "managed" && $this->user->id !== $user->getId()) { $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); + } $this->template->user = $user; $this->template->page = (int) ($this->queryParam("p") ?? 1); @@ -123,77 +129,84 @@ final class UserPresenter extends OpenVKPresenter } } - function renderPinClub(): void + public function renderPinClub(): void { $this->assertUserLoggedIn(); - $club = (new Clubs)->get((int) $this->queryParam("club")); - if(!$club) + $club = (new Clubs())->get((int) $this->queryParam("club")); + if (!$club) { $this->notFound(); + } - if(!$club->canBeModifiedBy($this->user->identity ?? NULL)) - $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied"), NULL, true); + if (!$club->canBeModifiedBy($this->user->identity ?? null)) { + $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied"), null, true); + } $isClubPinned = $this->user->identity->isClubPinned($club); - if(!$isClubPinned && $this->user->identity->getPinnedClubCount() > 10) - $this->flashFail("err", tr("error"), tr("error_max_pinned_clubs"), NULL, true); + if (!$isClubPinned && $this->user->identity->getPinnedClubCount() > 10) { + $this->flashFail("err", tr("error"), tr("error_max_pinned_clubs"), null, true); + } - if($club->getOwner()->getId() === $this->user->identity->getId()) { + if ($club->getOwner()->getId() === $this->user->identity->getId()) { $club->setOwner_Club_Pinned(!$isClubPinned); $club->save(); } else { $manager = $club->getManager($this->user->identity); - if(!is_null($manager)) { + if (!is_null($manager)) { $manager->setClub_Pinned(!$isClubPinned); $manager->save(); } } $this->returnJson([ - "success" => true + "success" => true, ]); } - - function renderEdit(): void + + public function renderEdit(): void { $this->assertUserLoggedIn(); - + $id = $this->user->id; #TODO: when ACL'll be done, allow admins to edit users via ?GUID=(chandler guid) - - if(!$id) + + if (!$id) { $this->notFound(); + } $user = $this->users->get($id); - if($_SERVER["REQUEST_METHOD"] === "POST") { + if ($_SERVER["REQUEST_METHOD"] === "POST") { $this->willExecuteWriteAction($_GET['act'] === "status"); - - if($_GET['act'] === "main" || $_GET['act'] == NULL) { + + if ($_GET['act'] === "main" || $_GET['act'] == null) { try { $user->setFirst_Name(empty($this->postParam("first_name")) ? $user->getFirstName() : $this->postParam("first_name")); $user->setLast_Name(empty($this->postParam("last_name")) ? "" : $this->postParam("last_name")); - } catch(InvalidUserNameException $ex) { + } catch (InvalidUserNameException $ex) { $this->flashFail("err", tr("error"), tr("invalid_real_name")); } - - $user->setPseudo(empty($this->postParam("pseudo")) ? NULL : $this->postParam("pseudo")); - $user->setStatus(empty($this->postParam("status")) ? NULL : $this->postParam("status")); - $user->setHometown(empty($this->postParam("hometown")) ? NULL : $this->postParam("hometown")); - - if (strtotime($this->postParam("birthday")) < time()) - $user->setBirthday(empty($this->postParam("birthday")) ? NULL : strtotime($this->postParam("birthday"))); + $user->setPseudo(empty($this->postParam("pseudo")) ? null : $this->postParam("pseudo")); + $user->setStatus(empty($this->postParam("status")) ? null : $this->postParam("status")); + $user->setHometown(empty($this->postParam("hometown")) ? null : $this->postParam("hometown")); - if ($this->postParam("birthday_privacy") <= 1 && $this->postParam("birthday_privacy") >= 0) - $user->setBirthday_Privacy($this->postParam("birthday_privacy")); - if ($this->postParam("marialstatus") <= 8 && $this->postParam("marialstatus") >= 0) - $user->setMarital_Status($this->postParam("marialstatus")); + if (strtotime($this->postParam("birthday")) < time()) { + $user->setBirthday(empty($this->postParam("birthday")) ? null : strtotime($this->postParam("birthday"))); + } + + if ($this->postParam("birthday_privacy") <= 1 && $this->postParam("birthday_privacy") >= 0) { + $user->setBirthday_Privacy($this->postParam("birthday_privacy")); + } + + if ($this->postParam("marialstatus") <= 8 && $this->postParam("marialstatus") >= 0) { + $user->setMarital_Status($this->postParam("marialstatus")); + } if ($this->postParam("maritalstatus-user")) { if (in_array((int) $this->postParam("marialstatus"), [0, 1, 8])) { - $user->setMarital_Status_User(NULL); + $user->setMarital_Status_User(null); } else { - $mUser = (new Users)->getByAddress($this->postParam("maritalstatus-user")); + $mUser = (new Users())->getByAddress($this->postParam("maritalstatus-user")); if ($mUser) { if ($mUser->getId() !== $this->user->id) { $user->setMarital_Status_User($mUser->getId()); @@ -201,129 +214,140 @@ final class UserPresenter extends OpenVKPresenter } } } - - if ($this->postParam("politViews") <= 9 && $this->postParam("politViews") >= 0) - $user->setPolit_Views($this->postParam("politViews")); - - if ($this->postParam("pronouns") <= 2 && $this->postParam("pronouns") >= 0) - switch ($this->postParam("pronouns")) { - case '0': - $user->setSex(0); - break; - case '1': - $user->setSex(1); - break; - case '2': - $user->setSex(2); - break; + + if ($this->postParam("politViews") <= 9 && $this->postParam("politViews") >= 0) { + $user->setPolit_Views($this->postParam("politViews")); + } + + if ($this->postParam("pronouns") <= 2 && $this->postParam("pronouns") >= 0) { + switch ($this->postParam("pronouns")) { + case '0': + $user->setSex(0); + break; + case '1': + $user->setSex(1); + break; + case '2': + $user->setSex(2); + break; + } } $user->setAudio_broadcast_enabled($this->checkbox("broadcast_music")); - - if(!empty($this->postParam("phone")) && $this->postParam("phone") !== $user->getPhone()) { - if(!OPENVK_ROOT_CONF["openvk"]["credentials"]["smsc"]["enable"]) + + if (!empty($this->postParam("phone")) && $this->postParam("phone") !== $user->getPhone()) { + if (!OPENVK_ROOT_CONF["openvk"]["credentials"]["smsc"]["enable"]) { $this->flashFail("err", tr("error_segmentation"), "котлетки"); - + } + $code = $user->setPhoneWithVerification($this->postParam("phone")); - - if(!Sms::send($this->postParam("phone"), "OPENVK - Your verification code is: $code")) + + if (!Sms::send($this->postParam("phone"), "OPENVK - Your verification code is: $code")) { $this->flashFail("err", tr("error_segmentation"), "котлетки: Remote err!"); + } } - } elseif($_GET['act'] === "contacts") { - if(empty($this->postParam("email_contact")) || Validator::i()->emailValid($this->postParam("email_contact"))) - $user->setEmail_Contact(empty($this->postParam("email_contact")) ? NULL : $this->postParam("email_contact")); - else + } elseif ($_GET['act'] === "contacts") { + if (empty($this->postParam("email_contact")) || Validator::i()->emailValid($this->postParam("email_contact"))) { + $user->setEmail_Contact(empty($this->postParam("email_contact")) ? null : $this->postParam("email_contact")); + } else { $this->flashFail("err", tr("invalid_email_address"), tr("invalid_email_address_comment")); + } $telegram = $this->postParam("telegram"); - if(empty($telegram) || Validator::i()->telegramValid($telegram)) - if(strpos($telegram, "t.me/") === 0) - $user->setTelegram(empty($telegram) ? NULL : substr($telegram, 5)); - else - $user->setTelegram(empty($telegram) ? NULL : ltrim($telegram, "@")); - else + if (empty($telegram) || Validator::i()->telegramValid($telegram)) { + if (strpos($telegram, "t.me/") === 0) { + $user->setTelegram(empty($telegram) ? null : substr($telegram, 5)); + } else { + $user->setTelegram(empty($telegram) ? null : ltrim($telegram, "@")); + } + } else { $this->flashFail("err", tr("invalid_telegram_name"), tr("invalid_telegram_name_comment")); + } + + $user->setCity(empty($this->postParam("city")) ? null : $this->postParam("city")); + $user->setAddress(empty($this->postParam("address")) ? null : $this->postParam("address")); - $user->setCity(empty($this->postParam("city")) ? NULL : $this->postParam("city")); - $user->setAddress(empty($this->postParam("address")) ? NULL : $this->postParam("address")); - $website = $this->postParam("website") ?? ""; - if(empty($website)) - $user->setWebsite(NULL); - else + if (empty($website)) { + $user->setWebsite(null); + } else { $user->setWebsite((!parse_url($website, PHP_URL_SCHEME) ? "https://" : "") . $website); - } elseif($_GET['act'] === "interests") { - $user->setInterests(empty($this->postParam("interests")) ? NULL : ovk_proc_strtr($this->postParam("interests"), 1000)); - $user->setFav_Music(empty($this->postParam("fav_music")) ? NULL : ovk_proc_strtr($this->postParam("fav_music"), 1000)); - $user->setFav_Films(empty($this->postParam("fav_films")) ? NULL : ovk_proc_strtr($this->postParam("fav_films"), 1000)); - $user->setFav_Shows(empty($this->postParam("fav_shows")) ? NULL : ovk_proc_strtr($this->postParam("fav_shows"), 1000)); - $user->setFav_Books(empty($this->postParam("fav_books")) ? NULL : ovk_proc_strtr($this->postParam("fav_books"), 1000)); - $user->setFav_Quote(empty($this->postParam("fav_quote")) ? NULL : ovk_proc_strtr($this->postParam("fav_quote"), 1000)); - $user->setFav_Games(empty($this->postParam("fav_games")) ? NULL : ovk_proc_strtr($this->postParam("fav_games"), 1000)); - $user->setAbout(empty($this->postParam("about")) ? NULL : ovk_proc_strtr($this->postParam("about"), 1000)); - } elseif($_GET["act"] === "backdrop") { - if($this->postParam("subact") === "remove") { + } + } elseif ($_GET['act'] === "interests") { + $user->setInterests(empty($this->postParam("interests")) ? null : ovk_proc_strtr($this->postParam("interests"), 1000)); + $user->setFav_Music(empty($this->postParam("fav_music")) ? null : ovk_proc_strtr($this->postParam("fav_music"), 1000)); + $user->setFav_Films(empty($this->postParam("fav_films")) ? null : ovk_proc_strtr($this->postParam("fav_films"), 1000)); + $user->setFav_Shows(empty($this->postParam("fav_shows")) ? null : ovk_proc_strtr($this->postParam("fav_shows"), 1000)); + $user->setFav_Books(empty($this->postParam("fav_books")) ? null : ovk_proc_strtr($this->postParam("fav_books"), 1000)); + $user->setFav_Quote(empty($this->postParam("fav_quote")) ? null : ovk_proc_strtr($this->postParam("fav_quote"), 1000)); + $user->setFav_Games(empty($this->postParam("fav_games")) ? null : ovk_proc_strtr($this->postParam("fav_games"), 1000)); + $user->setAbout(empty($this->postParam("about")) ? null : ovk_proc_strtr($this->postParam("about"), 1000)); + } elseif ($_GET["act"] === "backdrop") { + if ($this->postParam("subact") === "remove") { $user->unsetBackDropPictures(); $user->save(); $this->flashFail("succ", tr("backdrop_succ_rem"), tr("backdrop_succ_desc")); # will exit } - - $pic1 = $pic2 = NULL; + + $pic1 = $pic2 = null; try { - if($_FILES["backdrop1"]["error"] !== UPLOAD_ERR_NO_FILE) + if ($_FILES["backdrop1"]["error"] !== UPLOAD_ERR_NO_FILE) { $pic1 = Photo::fastMake($user->getId(), "Profile backdrop (system)", $_FILES["backdrop1"]); - - if($_FILES["backdrop2"]["error"] !== UPLOAD_ERR_NO_FILE) + } + + if ($_FILES["backdrop2"]["error"] !== UPLOAD_ERR_NO_FILE) { $pic2 = Photo::fastMake($user->getId(), "Profile backdrop (system)", $_FILES["backdrop2"]); - } catch(InvalidStateException $e) { + } + } catch (InvalidStateException $e) { $this->flashFail("err", tr("backdrop_error_title"), tr("backdrop_error_no_media")); } - - if($pic1 == $pic2 && is_null($pic1)) + + if ($pic1 == $pic2 && is_null($pic1)) { $this->flashFail("err", tr("backdrop_error_title"), tr("backdrop_error_no_media")); - + } + $user->setBackDropPictures($pic1, $pic2); $user->save(); $this->flashFail("succ", tr("backdrop_succ"), tr("backdrop_succ_desc")); - } elseif($_GET['act'] === "status") { - if(mb_strlen($this->postParam("status")) > 255) { + } elseif ($_GET['act'] === "status") { + if (mb_strlen($this->postParam("status")) > 255) { $statusLength = (string) mb_strlen($this->postParam("status")); - $this->flashFail("err", tr("error"), tr("error_status_too_long", $statusLength), NULL, true); + $this->flashFail("err", tr("error"), tr("error_status_too_long", $statusLength), null, true); } - $user->setStatus(empty($this->postParam("status")) ? NULL : $this->postParam("status")); + $user->setStatus(empty($this->postParam("status")) ? null : $this->postParam("status")); $user->setAudio_broadcast_enabled($this->postParam("broadcast") == 1); $user->save(); $this->returnJson([ - "success" => true + "success" => true, ]); - } elseif($_GET['act'] === "additional") { + } elseif ($_GET['act'] === "additional") { $maxAddFields = ovkGetQuirk("users.max-fields"); $items = []; - for($i = 0; $i < $maxAddFields; $i++) { - if(!$this->postParam("name_".$i)) { + for ($i = 0; $i < $maxAddFields; $i++) { + if (!$this->postParam("name_" . $i)) { continue; } $items[] = [ - "name" => $this->postParam("name_".$i), - "text" => $this->postParam("text_".$i), - "place" => $this->postParam("place_".$i), + "name" => $this->postParam("name_" . $i), + "text" => $this->postParam("text_" . $i), + "place" => $this->postParam("place_" . $i), ]; } \openvk\Web\Models\Entities\UserInfoEntities\AdditionalField::resetByOwner($this->user->id); - foreach($items as $new_field_info) { + foreach ($items as $new_field_info) { $name = ovk_proc_strtr($new_field_info["name"], 50); $text = ovk_proc_strtr($new_field_info["text"], 1000); - if(ctype_space($name) || ctype_space($text)) { + if (ctype_space($name) || ctype_space($text)) { continue; } - $place = (int)($new_field_info["place"]); + $place = (int) ($new_field_info["place"]); - $new_field = new \openvk\Web\Models\Entities\UserInfoEntities\AdditionalField; + $new_field = new \openvk\Web\Models\Entities\UserInfoEntities\AdditionalField(); $new_field->setOwner($this->user->id); $new_field->setName($name); $new_field->setText($text); @@ -332,82 +356,91 @@ final class UserPresenter extends OpenVKPresenter $new_field->save(); } } - + try { - if($_GET['act'] !== "additional") { + if ($_GET['act'] !== "additional") { $user->save(); } - } catch(\PDOException $ex) { - if($ex->getCode() == 23000) + } catch (\PDOException $ex) { + if ($ex->getCode() == 23000) { $this->flashFail("err", tr("error"), tr("error_shorturl")); - else + } else { throw $ex; + } } - + $this->flash("succ", tr("changes_saved"), tr("changes_saved_comment")); } - + $this->template->mode = in_array($this->queryParam("act"), [ - "main", "contacts", "interests", "avatar", "backdrop", "additional" + "main", "contacts", "interests", "avatar", "backdrop", "additional", ]) ? $this->queryParam("act") : "main"; - + $this->template->user = $user; } - - function renderVerifyPhone(): void + + public function renderVerifyPhone(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - + $user = $this->user->identity; - if(!$user->hasPendingNumberChange()) + if (!$user->hasPendingNumberChange()) { exit; - else + } else { $this->template->change = $user->getPendingPhoneVerification(); - - if($_SERVER["REQUEST_METHOD"] === "POST") { - if(!$user->verifyNumber($this->postParam("code") ?? 0)) + } + + if ($_SERVER["REQUEST_METHOD"] === "POST") { + if (!$user->verifyNumber($this->postParam("code") ?? 0)) { $this->flashFail("err", tr("error"), tr("invalid_code")); - + } + $this->flash("succ", tr("changes_saved"), tr("changes_saved_comment")); } } - - function renderSub(): void + + public function renderSub(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - - if($_SERVER["REQUEST_METHOD"] !== "POST") exit("Invalid state"); - + + if ($_SERVER["REQUEST_METHOD"] !== "POST") { + exit("Invalid state"); + } + $user = $this->users->get((int) $this->postParam("id")); - if(!$user) exit("Invalid state"); - - if ($this->postParam("act") == "rej") + if (!$user) { + exit("Invalid state"); + } + + if ($this->postParam("act") == "rej") { $user->changeFlags($this->user->identity, 0b10000000, true); - else + } else { $user->toggleSubscription($this->user->identity); - + } + $this->redirect($_SERVER['HTTP_REFERER']); } - - function renderSetAvatar() { + + public function renderSetAvatar() + { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - - $photo = new Photo; + + $photo = new Photo(); try { $photo->setOwner($this->user->id); $photo->setDescription("Profile image"); $photo->setFile($_FILES["blob"]); $photo->setCreated(time()); $photo->save(); - } catch(\Throwable $ex) { - $this->flashFail("err", tr("error"), tr("error_upload_failed"), NULL, (int)$this->postParam("ajax", true) == 1); + } catch (\Throwable $ex) { + $this->flashFail("err", tr("error"), tr("error_upload_failed"), null, (int) $this->postParam("ajax", true) == 1); } - - $album = (new Albums)->getUserAvatarAlbum($this->user->identity); + + $album = (new Albums())->getUserAvatarAlbum($this->user->identity); $album->addPhoto($photo); $album->setEdited(time()); $album->save(); @@ -415,8 +448,8 @@ final class UserPresenter extends OpenVKPresenter $flags = 0; $flags |= 0b00010000; - if($this->postParam("on_wall") == 1) { - $post = new Post; + if ($this->postParam("on_wall") == 1) { + $post = new Post(); $post->setOwner($this->user->id); $post->setWall($this->user->id); $post->setCreated(time()); @@ -427,7 +460,7 @@ final class UserPresenter extends OpenVKPresenter $post->attach($photo); } - if((int)$this->postParam("ajax", true) == 1) { + if ((int) $this->postParam("ajax", true) == 1) { $this->returnJson([ "success" => true, "new_photo" => $photo->getPrettyId(), @@ -438,91 +471,102 @@ final class UserPresenter extends OpenVKPresenter } } - function renderDeleteAvatar() { + public function renderDeleteAvatar() + { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); $avatar = $this->user->identity->getAvatarPhoto(); - if(!$avatar) - $this->flashFail("succ", tr("error"), "no avatar bro", NULL, true); + if (!$avatar) { + $this->flashFail("succ", tr("error"), "no avatar bro", null, true); + } $avatar->isolate(); $newAvatar = $this->user->identity->getAvatarPhoto(); - if(!$newAvatar) + if (!$newAvatar) { $this->returnJson([ "success" => true, "has_new_photo" => false, - "new_photo" => NULL, + "new_photo" => null, "url" => "/assets/packages/static/openvk/img/camera_200.png", ]); - else + } else { $this->returnJson([ "success" => true, "has_new_photo" => true, "new_photo" => $newAvatar->getPrettyId(), "url" => $newAvatar->getURL(), ]); + } } - - function renderSettings(): void + + public function renderSettings(): void { $this->assertUserLoggedIn(); - - $id = $this->user->id; #TODO: when ACL'll be done, allow admins to edit users via ?GUID=(chandler guid) - - if(!$id) - $this->notFound(); - if(in_array($this->queryParam("act"), ["finance", "finance.top-up"]) && !OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"]) + $id = $this->user->id; #TODO: when ACL'll be done, allow admins to edit users via ?GUID=(chandler guid) + + if (!$id) { + $this->notFound(); + } + + if (in_array($this->queryParam("act"), ["finance", "finance.top-up"]) && !OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"]) { $this->flashFail("err", tr("error"), tr("feature_disabled")); - + } + $user = $this->users->get($id); - if($_SERVER["REQUEST_METHOD"] === "POST") { + if ($_SERVER["REQUEST_METHOD"] === "POST") { $this->willExecuteWriteAction(); - - if($_GET['act'] === "main" || $_GET['act'] == NULL) { - if($this->postParam("old_pass") && $this->postParam("new_pass") && $this->postParam("repeat_pass")) { - if($this->postParam("new_pass") === $this->postParam("repeat_pass")) { - if($this->user->identity->is2faEnabled()) { + + if ($_GET['act'] === "main" || $_GET['act'] == null) { + if ($this->postParam("old_pass") && $this->postParam("new_pass") && $this->postParam("repeat_pass")) { + if ($this->postParam("new_pass") === $this->postParam("repeat_pass")) { + if ($this->user->identity->is2faEnabled()) { $code = $this->postParam("password_change_code"); - if(!($code === (new Totp)->GenerateToken(Base32::decode($this->user->identity->get2faSecret())) || $this->user->identity->use2faBackupCode((int) $code))) + if (!($code === (new Totp())->GenerateToken(Base32::decode($this->user->identity->get2faSecret())) || $this->user->identity->use2faBackupCode((int) $code))) { $this->flashFail("err", tr("error"), tr("incorrect_2fa_code")); + } } - if(!$this->user->identity->getChandlerUser()->updatePassword($this->postParam("new_pass"), $this->postParam("old_pass"))) + if (!$this->user->identity->getChandlerUser()->updatePassword($this->postParam("new_pass"), $this->postParam("old_pass"))) { $this->flashFail("err", tr("error"), tr("error_old_password")); + } } else { $this->flashFail("err", tr("error"), tr("error_new_password")); } } - if($this->postParam("new_email")) { - if(!Validator::i()->emailValid($this->postParam("new_email"))) + if ($this->postParam("new_email")) { + if (!Validator::i()->emailValid($this->postParam("new_email"))) { $this->flashFail("err", tr("invalid_email_address"), tr("invalid_email_address_comment")); - - if(!Authenticator::verifyHash($this->postParam("email_change_pass"), $user->getChandlerUser()->getRaw()->passwordHash)) - $this->flashFail("err", tr("error"), tr("incorrect_password")); - - if($user->is2faEnabled()) { - $code = $this->postParam("email_change_code"); - if(!($code === (new Totp)->GenerateToken(Base32::decode($user->get2faSecret())) || $user->use2faBackupCode((int) $code))) - $this->flashFail("err", tr("error"), tr("incorrect_2fa_code")); } - if($this->postParam("new_email") !== $user->getEmail()) { - if (OPENVK_ROOT_CONF['openvk']['preferences']['security']['requireEmail']) { - $request = (new EmailChangeVerifications)->getLatestByUser($user); - if(!is_null($request) && $request->isNew()) + if (!Authenticator::verifyHash($this->postParam("email_change_pass"), $user->getChandlerUser()->getRaw()->passwordHash)) { + $this->flashFail("err", tr("error"), tr("incorrect_password")); + } + + if ($user->is2faEnabled()) { + $code = $this->postParam("email_change_code"); + if (!($code === (new Totp())->GenerateToken(Base32::decode($user->get2faSecret())) || $user->use2faBackupCode((int) $code))) { + $this->flashFail("err", tr("error"), tr("incorrect_2fa_code")); + } + } + + if ($this->postParam("new_email") !== $user->getEmail()) { + if (OPENVK_ROOT_CONF['openvk']['preferences']['security']['requireEmail']) { + $request = (new EmailChangeVerifications())->getLatestByUser($user); + if (!is_null($request) && $request->isNew()) { $this->flashFail("err", tr("forbidden"), tr("email_rate_limit_error")); - - $verification = new EmailChangeVerification; + } + + $verification = new EmailChangeVerification(); $verification->setProfile($user->getId()); $verification->setNew_Email($this->postParam("new_email")); $verification->save(); - + $params = [ "key" => $verification->getKey(), "name" => $user->getCanonicalName(), @@ -530,18 +574,19 @@ final class UserPresenter extends OpenVKPresenter $this->sendmail($this->postParam("new_email"), "change-email", $params); #Vulnerability possible $this->flashFail("succ", tr("information_-1"), tr("email_change_confirm_message")); } - + try { $user->changeEmail($this->postParam("new_email")); - } catch(UniqueConstraintViolationException $ex) { + } catch (UniqueConstraintViolationException $ex) { $this->flashFail("err", tr("error"), tr("user_already_exists")); - } + } } } - - if(!$user->setShortCode(empty($this->postParam("sc")) ? NULL : $this->postParam("sc"))) + + if (!$user->setShortCode(empty($this->postParam("sc")) ? null : $this->postParam("sc"))) { $this->flashFail("err", tr("error"), tr("error_shorturl_incorrect")); - } else if($_GET['act'] === "privacy") { + } + } elseif ($_GET['act'] === "privacy") { $settings = [ "page.read", "page.info.read", @@ -556,51 +601,59 @@ final class UserPresenter extends OpenVKPresenter "audios.read", "likes.read", ]; - foreach($settings as $setting) { + foreach ($settings as $setting) { $input = $this->postParam(str_replace(".", "_", $setting)); - $user->setPrivacySetting($setting, min(3, (int)abs((int)$input ?? $user->getPrivacySetting($setting)))); + $user->setPrivacySetting($setting, min(3, (int) abs((int) $input ?? $user->getPrivacySetting($setting)))); } - $prof = $this->postParam("profile_type") == 1 || $this->postParam("profile_type") == 0 ? (int)$this->postParam("profile_type") : 0; + $prof = $this->postParam("profile_type") == 1 || $this->postParam("profile_type") == 0 ? (int) $this->postParam("profile_type") : 0; $user->setProfile_type($prof); - - } else if($_GET['act'] === "finance.top-up") { + + } elseif ($_GET['act'] === "finance.top-up") { $token = $this->postParam("key0") . $this->postParam("key1") . $this->postParam("key2") . $this->postParam("key3"); - $voucher = (new Vouchers)->getByToken($token); - if(!$voucher) + $voucher = (new Vouchers())->getByToken($token); + if (!$voucher) { $this->flashFail("err", tr("invalid_voucher"), tr("voucher_bad")); - + } + $perm = $voucher->willUse($user); - if(!$perm) + if (!$perm) { $this->flashFail("err", tr("invalid_voucher"), tr("voucher_bad")); - + } + $user->setCoins($user->getCoins() + $voucher->getCoins()); $user->setRating($user->getRating() + $voucher->getRating()); $user->save(); - + $this->flashFail("succ", tr("voucher_good"), tr("voucher_redeemed")); - } else if($_GET['act'] === "interface") { - if (isset(Themepacks::i()[$this->postParam("style")]) || $this->postParam("style") === Themepacks::DEFAULT_THEME_ID) - { - if ($this->postParam("theme_for_session") != "1") $user->setStyle($this->postParam("style")); - $this->setSessionTheme($this->postParam("style")); - } - - if ($this->postParam("style_avatar") <= 2 && $this->postParam("style_avatar") >= 0) - $user->setStyle_Avatar((int)$this->postParam("style_avatar")); - - if (in_array($this->postParam("rating"), [0, 1])) + } elseif ($_GET['act'] === "interface") { + if (isset(Themepacks::i()[$this->postParam("style")]) || $this->postParam("style") === Themepacks::DEFAULT_THEME_ID) { + if ($this->postParam("theme_for_session") != "1") { + $user->setStyle($this->postParam("style")); + } + $this->setSessionTheme($this->postParam("style")); + } + + if ($this->postParam("style_avatar") <= 2 && $this->postParam("style_avatar") >= 0) { + $user->setStyle_Avatar((int) $this->postParam("style_avatar")); + } + + if (in_array($this->postParam("rating"), [0, 1])) { $user->setShow_Rating((int) $this->postParam("rating")); + } - if (in_array($this->postParam("microblog"), [0, 1])) + if (in_array($this->postParam("microblog"), [0, 1])) { $user->setMicroblog((int) $this->postParam("microblog")); - - if(in_array($this->postParam("nsfw"), [0, 1, 2])) - $user->setNsfwTolerance((int) $this->postParam("nsfw")); + } - if(in_array($this->postParam("main_page"), [0, 1])) + if (in_array($this->postParam("nsfw"), [0, 1, 2])) { + $user->setNsfwTolerance((int) $this->postParam("nsfw")); + } + + if (in_array($this->postParam("main_page"), [0, 1])) { $user->setMain_Page((int) $this->postParam("main_page")); - } else if($_GET['act'] === "lMenu") { + } + } elseif ($_GET['act'] === "lMenu") { $settings = [ "menu_bildoj" => "photos", "menu_muziko" => "audios", @@ -614,37 +667,39 @@ final class UserPresenter extends OpenVKPresenter "menu_aplikoj" => "apps", "menu_doxc" => "docs", ]; - foreach($settings as $checkbox => $setting) + foreach ($settings as $checkbox => $setting) { $user->setLeftMenuItemStatus($setting, $this->checkbox($checkbox)); + } } - + try { $user->save(); - } catch(\PDOException $ex) { - if($ex->getCode() == 23000) + } catch (\PDOException $ex) { + if ($ex->getCode() == 23000) { $this->flashFail("err", tr("error"), tr("error_shorturl")); - else + } else { throw $ex; + } } - - $this->flash("succ", tr("changes_saved"), tr("changes_saved_comment")); + + $this->flash("succ", tr("changes_saved"), tr("changes_saved_comment")); } $this->template->mode = in_array($this->queryParam("act"), [ - "main", "security", "privacy", "finance", "finance.top-up", "interface", "blacklist" + "main", "security", "privacy", "finance", "finance.top-up", "interface", "blacklist", ]) ? $this->queryParam("act") : "main"; - if($this->template->mode == "finance") { + if ($this->template->mode == "finance") { $address = OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["address"]; $text = str_replace("$1", (string) $this->user->identity->getId(), OPENVK_ROOT_CONF["openvk"]["preferences"]["ton"]["hint"]); $qrCode = explode("base64,", (new QRCode(new QROptions([ - "imageTransparent" => false + "imageTransparent" => false, ])))->render("ton://transfer/$address?text=$text")); $this->template->qrCodeType = substr($qrCode[0], 5); $this->template->qrCodeData = $qrCode[1]; - } else if($this->template->mode === "blacklist") { - $page = (int)($this->queryParam('p') ?? 1); + } elseif ($this->template->mode === "blacklist") { + $page = (int) ($this->queryParam('p') ?? 1); $count = 10; $offset = ($page - 1) * $count; @@ -657,12 +712,12 @@ final class UserPresenter extends OpenVKPresenter "perPage" => OPENVK_DEFAULT_PER_PAGE, ]; } - + $this->template->user = $user; $this->template->themes = Themepacks::i()->getThemeList(); } - function renderDeactivate(): void + public function renderDeactivate(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); @@ -671,10 +726,10 @@ final class UserPresenter extends OpenVKPresenter $reason = $this->postParam("deactivate_reason"); $share = $this->postParam("deactivate_share"); - if($share) { + if ($share) { $flags |= 0b00100000; - $post = new Post; + $post = new Post(); $post->setOwner($this->user->id); $post->setWall($this->user->id); $post->setCreated(time()); @@ -688,14 +743,15 @@ final class UserPresenter extends OpenVKPresenter $this->redirect("/"); } - function renderTwoFactorAuthSettings(): void + public function renderTwoFactorAuthSettings(): void { $this->assertUserLoggedIn(); - if($this->user->identity->is2faEnabled()) { - if($_SERVER["REQUEST_METHOD"] === "POST") { - if(!Authenticator::verifyHash($this->postParam("password"), $this->user->identity->getChandlerUser()->getRaw()->passwordHash)) + if ($this->user->identity->is2faEnabled()) { + if ($_SERVER["REQUEST_METHOD"] === "POST") { + if (!Authenticator::verifyHash($this->postParam("password"), $this->user->identity->getChandlerUser()->getRaw()->passwordHash)) { $this->flashFail("err", tr("error"), tr("incorrect_password")); + } $this->user->identity->generate2faBackupCodes(); $this->template->_template = "User/TwoFactorAuthCodes.xml"; @@ -707,16 +763,17 @@ final class UserPresenter extends OpenVKPresenter } $secret = Base32::encode(Totp::GenerateSecret(16)); - if($_SERVER["REQUEST_METHOD"] === "POST") { + if ($_SERVER["REQUEST_METHOD"] === "POST") { $this->willExecuteWriteAction(); - if(!Authenticator::verifyHash($this->postParam("password"), $this->user->identity->getChandlerUser()->getRaw()->passwordHash)) + if (!Authenticator::verifyHash($this->postParam("password"), $this->user->identity->getChandlerUser()->getRaw()->passwordHash)) { $this->flashFail("err", tr("error"), tr("incorrect_password")); + } $secret = $this->postParam("secret"); $code = $this->postParam("code"); - if($code === (new Totp)->GenerateToken(Base32::decode($secret))) { + if ($code === (new Totp())->GenerateToken(Base32::decode($secret))) { $this->user->identity->set2fa_secret($secret); $this->user->identity->save(); @@ -735,33 +792,34 @@ final class UserPresenter extends OpenVKPresenter $issuer = OPENVK_ROOT_CONF["openvk"]["appearance"]["name"]; $email = $this->user->identity->getEmail(); $qrCode = explode("base64,", (new QRCode(new QROptions([ - "imageTransparent" => false + "imageTransparent" => false, ])))->render("otpauth://totp/$issuer:$email?secret=$secret&issuer=$issuer")); $this->template->qrCodeType = substr($qrCode[0], 5); $this->template->qrCodeData = $qrCode[1]; } - function renderDisableTwoFactorAuth(): void + public function renderDisableTwoFactorAuth(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - if(!Authenticator::verifyHash($this->postParam("password"), $this->user->identity->getChandlerUser()->getRaw()->passwordHash)) + if (!Authenticator::verifyHash($this->postParam("password"), $this->user->identity->getChandlerUser()->getRaw()->passwordHash)) { $this->flashFail("err", tr("error"), tr("incorrect_password")); + } - $this->user->identity->set2fa_secret(NULL); + $this->user->identity->set2fa_secret(null); $this->user->identity->save(); $this->flashFail("succ", tr("information_-1"), tr("two_factor_authentication_disabled_message")); } - function renderResetThemepack(): void + public function renderResetThemepack(): void { $this->assertNoCSRF(); $this->setSessionTheme(Themepacks::DEFAULT_THEME_ID); - if($this->user) { + if ($this->user) { $this->willExecuteWriteAction(); $this->user->identity->setStyle(Themepacks::DEFAULT_THEME_ID); @@ -771,35 +829,41 @@ final class UserPresenter extends OpenVKPresenter $this->redirect("/"); } - function renderCoinsTransfer(): void + public function renderCoinsTransfer(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - if(!OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"]) + if (!OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"]) { $this->flashFail("err", tr("error"), tr("feature_disabled")); + } $receiverAddress = $this->postParam("receiver"); $value = (int) $this->postParam("value"); $message = $this->postParam("message"); - if(!$receiverAddress || !$value) + if (!$receiverAddress || !$value) { $this->flashFail("err", tr("failed_to_tranfer_points"), tr("not_all_information_has_been_entered")); + } - if($value < 0) + if ($value < 0) { $this->flashFail("err", tr("failed_to_tranfer_points"), tr("negative_transfer_value")); + } - if(iconv_strlen($message) > 255) + if (iconv_strlen($message) > 255) { $this->flashFail("err", tr("failed_to_tranfer_points"), tr("message_is_too_long")); + } $receiver = $this->users->getByAddress($receiverAddress); - if(!$receiver || !$receiver->canBeViewedBy($this->user->identity)) + if (!$receiver || !$receiver->canBeViewedBy($this->user->identity)) { $this->flashFail("err", tr("failed_to_tranfer_points"), tr("receiver_not_found")); + } - if($this->user->identity->getCoins() < $value) + if ($this->user->identity->getCoins() < $value) { $this->flashFail("err", tr("failed_to_tranfer_points"), tr("you_dont_have_enough_points")); + } - if($this->user->id !== $receiver->getId()) { + if ($this->user->id !== $receiver->getId()) { $this->user->identity->setCoins($this->user->identity->getCoins() - $value); $this->user->identity->save(); @@ -812,33 +876,39 @@ final class UserPresenter extends OpenVKPresenter $this->flashFail("succ", tr("information_-1"), tr("points_transfer_successful", tr("points_amount", $value), $receiver->getURL(), htmlentities($receiver->getCanonicalName()))); } - function renderIncreaseRating(): void + public function renderIncreaseRating(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - if(!OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"]) + if (!OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"]) { $this->flashFail("err", tr("error"), tr("feature_disabled")); + } $receiverAddress = $this->postParam("receiver"); $value = (int) $this->postParam("value"); $message = $this->postParam("message"); - if(!$receiverAddress || !$value) + if (!$receiverAddress || !$value) { $this->flashFail("err", tr("failed_to_increase_rating"), tr("not_all_information_has_been_entered")); + } - if($value < 0) + if ($value < 0) { $this->flashFail("err", tr("failed_to_increase_rating"), tr("negative_rating_value")); + } - if(iconv_strlen($message) > 255) + if (iconv_strlen($message) > 255) { $this->flashFail("err", tr("failed_to_increase_rating"), tr("message_is_too_long")); + } $receiver = $this->users->getByAddress($receiverAddress); - if(!$receiver) + if (!$receiver) { $this->flashFail("err", tr("failed_to_increase_rating"), tr("receiver_not_found")); + } - if($this->user->identity->getCoins() < $value) + if ($this->user->identity->getCoins() < $value) { $this->flashFail("err", tr("failed_to_increase_rating"), tr("you_dont_have_enough_points")); + } $this->user->identity->setCoins($this->user->identity->getCoins() - $value); $this->user->identity->save(); @@ -846,16 +916,17 @@ final class UserPresenter extends OpenVKPresenter $receiver->setRating($receiver->getRating() + $value); $receiver->save(); - if($this->user->id !== $receiver->getId()) + if ($this->user->id !== $receiver->getId()) { (new RatingUpNotification($receiver, $this->user->identity, $value, $message))->emit(); + } $this->flashFail("succ", tr("information_-1"), tr("rating_increase_successful", $receiver->getURL(), htmlentities($receiver->getCanonicalName()), $value)); } - function renderEmailChangeFinish(): void + public function renderEmailChangeFinish(): void { - $request = (new EmailChangeVerifications)->getByToken(str_replace(" ", "+", $this->queryParam("key"))); - if(!$request || !$request->isStillValid()) { + $request = (new EmailChangeVerifications())->getByToken(str_replace(" ", "+", $this->queryParam("key"))); + if (!$request || !$request->isStillValid()) { $this->flash("err", tr("token_manipulation_error"), tr("token_manipulation_error_comment")); $this->redirect("/settings"); } else { @@ -863,7 +934,7 @@ final class UserPresenter extends OpenVKPresenter try { $request->getUser()->changeEmail($request->getNewEmail()); - } catch(UniqueConstraintViolationException $ex) { + } catch (UniqueConstraintViolationException $ex) { $this->flashFail("err", tr("error"), tr("user_already_exists")); } diff --git a/Web/Presenters/VKAPIPresenter.php b/Web/Presenters/VKAPIPresenter.php index a214f49f..61ee33fa 100644 --- a/Web/Presenters/VKAPIPresenter.php +++ b/Web/Presenters/VKAPIPresenter.php @@ -1,5 +1,9 @@ - $code, "error_msg" => $message, @@ -38,10 +42,11 @@ final class VKAPIPresenter extends OpenVKPresenter ], ], ]; - - foreach($_GET as $key => $value) + + foreach ($_GET as $key => $value) { array_unshift($payload["request_params"], [ "key" => $key, "value" => $value ]); - + } + exit(json_encode($payload)); } @@ -49,48 +54,50 @@ final class VKAPIPresenter extends OpenVKPresenter { header("HTTP/1.1 401 Unauthorized"); header("Content-Type: application/json"); - + $payload = [ "error" => "need_validation", "error_description" => "use app code", "validation_type" => "2fa_app", - "validation_sid" => "2fa_".$userId."_2839041_randommessdontread", + "validation_sid" => "2fa_" . $userId . "_2839041_randommessdontread", "phone_mask" => "+374 ** *** 420", "redirect_url" => "https://http.cat/418", // Not implemented yet :( So there is a photo of cat :3 - "validation_resend" => "nowhere" + "validation_resend" => "nowhere", ]; - + exit(json_encode($payload)); } - + private function badMethod(string $object, string $method): void { $this->fail(3, "Unknown method passed.", $object, $method); } - + private function badMethodCall(string $object, string $method, string $param): void { $this->fail(100, "Required parameter '$param' missing.", $object, $method); } - - function onStartup(): void + + public function onStartup(): void { parent::onStartup(); - + # idk, but in case we will ever support non-standard HTTP credential authflow $origin = "*"; - if(isset($_SERVER["HTTP_REFERER"])) { + if (isset($_SERVER["HTTP_REFERER"])) { $refOrigin = parse_url($_SERVER["HTTP_REFERER"], PHP_URL_SCHEME) . "://" . parse_url($_SERVER["HTTP_REFERER"], PHP_URL_HOST); - if($refOrigin !== false) + if ($refOrigin !== false) { $origin = $refOrigin; + } } - - if(!is_null($this->queryParam("requestPort"))) + + if (!is_null($this->queryParam("requestPort"))) { $origin .= ":" . ((int) $this->queryParam("requestPort")); - + } + header("Access-Control-Allow-Origin: $origin"); - - if($_SERVER["REQUEST_METHOD"] === "OPTIONS") { + + if ($_SERVER["REQUEST_METHOD"] === "OPTIONS") { header("Access-Control-Allow-Methods: POST, PUT, DELETE"); header("Access-Control-Allow-Headers: " . $_SERVER["HTTP_ACCESS_CONTROL_REQUEST_HEADERS"]); header("Access-Control-Max-Age: -1"); @@ -98,18 +105,18 @@ final class VKAPIPresenter extends OpenVKPresenter } } - function renderPhotoUpload(string $signature): void + public function renderPhotoUpload(string $signature): void { $secret = CHANDLER_ROOT_CONF["security"]["secret"]; $queryString = rawurldecode($_SERVER["QUERY_STRING"]); $computedSignature = hash_hmac("sha3-224", $queryString, $secret); - if(!(strlen($signature) == 56 && sodium_memcmp($signature, $computedSignature) == 0)) { + if (!(strlen($signature) == 56 && sodium_memcmp($signature, $computedSignature) == 0)) { header("HTTP/1.1 422 Unprocessable Entity"); exit("Try harder <3"); } $data = unpack("vDOMAIN/Z10FIELD/vMF/vMP/PTIME/PUSER/PGROUP", base64_decode($queryString)); - if((time() - $data["TIME"]) > 600) { + if ((time() - $data["TIME"]) > 600) { header("HTTP/1.1 422 Unprocessable Entity"); exit("Expired"); } @@ -118,21 +125,21 @@ final class VKAPIPresenter extends OpenVKPresenter $maxSize = OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["api"]["maxFileSize"]; $maxFiles = OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["api"]["maxFilesPerDomain"]; $usrFiles = sizeof(glob("$folder/$data[USER]_*.oct")); - if($usrFiles >= $maxFiles) { + if ($usrFiles >= $maxFiles) { header("HTTP/1.1 507 Insufficient Storage"); exit("There are $maxFiles pending already. Please save them before uploading more :3"); } # Not multifile - if($data["MF"] === 0) { + if ($data["MF"] === 0) { $file = $_FILES[$data["FIELD"]]; - if(!$file) { + if (!$file) { header("HTTP/1.0 400"); exit("No file"); - } else if($file["error"] != UPLOAD_ERR_OK) { + } elseif ($file["error"] != UPLOAD_ERR_OK) { header("HTTP/1.0 500"); exit("File could not be consumed"); - } else if($file["size"] > $maxSize) { + } elseif ($file["size"] > $maxSize) { header("HTTP/1.0 507 Insufficient Storage"); exit("File is too big"); } @@ -149,14 +156,15 @@ final class VKAPIPresenter extends OpenVKPresenter } $files = []; - for($i = 1; $i <= 5; $i++) { - $file = $_FILES[$data["FIELD"] . $i] ?? NULL; + for ($i = 1; $i <= 5; $i++) { + $file = $_FILES[$data["FIELD"] . $i] ?? null; if (!$file || $file["error"] != UPLOAD_ERR_OK || $file["size"] > $maxSize) { continue; - } else if((sizeof($files) + $usrFiles) > $maxFiles) { + } elseif ((sizeof($files) + $usrFiles) > $maxFiles) { # Clear uploaded files since they can't be saved anyway - foreach($files as $f) + foreach ($files as $f) { unlink($f); + } header("HTTP/1.1 507 Insufficient Storage"); exit("There are $maxFiles pending already. Please save them before uploading more :3"); @@ -165,14 +173,15 @@ final class VKAPIPresenter extends OpenVKPresenter $files[++$usrFiles] = move_uploaded_file($file["tmp_name"], "$folder/$data[USER]_$usrFiles.oct"); } - if(sizeof($files) === 0) { + if (sizeof($files) === 0) { header("HTTP/1.0 400"); exit("No file"); } $filesManifest = []; - foreach($files as $id => $file) + foreach ($files as $id => $file) { $filesManifest[] = ["keyholder" => $data["USER"], "resource" => $id, "club" => $data["GROUP"]]; + } $filesManifest = json_encode($filesManifest); $manifestHash = hash_hmac("sha3-224", $filesManifest, $secret); @@ -184,69 +193,76 @@ final class VKAPIPresenter extends OpenVKPresenter "hash" => $manifestHash, ])); } - - function renderRoute(string $object, string $method): void + + public function renderRoute(string $object, string $method): void { $callback = $this->queryParam("callback"); $authMechanism = $this->queryParam("auth_mechanism") ?? "token"; - if($authMechanism === "roaming") { - if($callback) + if ($authMechanism === "roaming") { + if ($callback) { $this->fail(-1, "User authorization failed: roaming mechanism is unavailable with jsonp.", $object, $method); + } - if(!$this->user->identity) + if (!$this->user->identity) { $this->fail(5, "User authorization failed: roaming mechanism is selected, but user is not logged in.", $object, $method); - else - $identity = $this->user->identity; - } else { - if(is_null($this->requestParam("access_token"))) { - $identity = NULL; } else { - $token = (new APITokens)->getByCode($this->requestParam("access_token")); - if(!$token) { - $identity = NULL; + $identity = $this->user->identity; + } + } else { + if (is_null($this->requestParam("access_token"))) { + $identity = null; + } else { + $token = (new APITokens())->getByCode($this->requestParam("access_token")); + if (!$token) { + $identity = null; } else { $identity = $token->getUser(); $platform = $token->getPlatform(); } } } - - if(!is_null($identity) && $identity->isBanned()) + + if (!is_null($identity) && $identity->isBanned()) { $this->fail(18, "User account is deactivated", $object, $method); - + } + $object = ucfirst(strtolower($object)); $handlerClass = "openvk\\VKAPI\\Handlers\\$object"; - if(!class_exists($handlerClass)) + if (!class_exists($handlerClass)) { $this->badMethod($object, $method); - + } + $handler = new $handlerClass($identity, $platform); - if(!is_callable([$handler, $method])) + if (!is_callable([$handler, $method])) { $this->badMethod($object, $method); - + } + $has_rss = false; $route = new \ReflectionMethod($handler, $method); $params = []; - foreach($route->getParameters() as $parameter) { - if($parameter->getName() == 'rss') + foreach ($route->getParameters() as $parameter) { + if ($parameter->getName() == 'rss') { $has_rss = true; + } $val = $this->requestParam($parameter->getName()); - if(is_null($val)) { - if($parameter->allowsNull()) - $val = NULL; - else if($parameter->isDefaultValueAvailable()) + if (is_null($val)) { + if ($parameter->allowsNull()) { + $val = null; + } elseif ($parameter->isDefaultValueAvailable()) { $val = $parameter->getDefaultValue(); - else if($parameter->isOptional()) - $val = NULL; - else + } elseif ($parameter->isOptional()) { + $val = null; + } else { $this->badMethodCall($object, $method, $parameter->getName()); + } } - + try { // Проверка типа параметра $type = $parameter->getType(); if (($type && !$type->isBuiltin()) || is_null($val)) { - $params[] = $val; + $params[] = $val; } else { settype($val, $parameter->getType()->getName()); $params[] = $val; @@ -256,18 +272,18 @@ final class VKAPIPresenter extends OpenVKPresenter // some args are intended for internal use } } - + define("VKAPI_DECL_VER", $this->requestParam("v") ?? "4.100", false); - + try { $res = $handler->{$method}(...$params); - } catch(APIErrorException $ex) { + } catch (APIErrorException $ex) { $this->fail($ex->getCode(), $ex->getMessage(), $object, $method); } - - $result = NULL; - if($this->queryParam("rss") == '1' && $has_rss) { + $result = null; + + if ($this->queryParam("rss") == '1' && $has_rss) { $feed = new \Bhaktaraz\RSSGenerator\Feed(); $res->appendTo($feed); @@ -279,66 +295,71 @@ final class VKAPIPresenter extends OpenVKPresenter "response" => $res, ]); - if($callback) { + if ($callback) { $result = $callback . '(' . $result . ')'; header('Content-Type: application/javascript'); } else { header("Content-Type: application/json"); } } - + $size = strlen($result); header("Content-Length: $size"); exit($result); } - - function renderTokenLogin(): void + + public function renderTokenLogin(): void { - if($this->requestParam("grant_type") !== "password") + if ($this->requestParam("grant_type") !== "password") { $this->fail(7, "Invalid grant type", "internal", "acquireToken"); - else if(is_null($this->requestParam("username")) || is_null($this->requestParam("password"))) + } elseif (is_null($this->requestParam("username")) || is_null($this->requestParam("password"))) { $this->fail(100, "Password and username not passed", "internal", "acquireToken"); - + } + $chUser = DB::i()->getContext()->table("ChandlerUsers")->where("login", $this->requestParam("username"))->fetch(); - if(!$chUser) + if (!$chUser) { $this->fail(28, "Invalid username or password", "internal", "acquireToken"); - + } + $auth = Authenticator::i(); - if(!$auth->verifyCredentials($chUser->id, $this->requestParam("password"))) + if (!$auth->verifyCredentials($chUser->id, $this->requestParam("password"))) { $this->fail(28, "Invalid username or password", "internal", "acquireToken"); - + } + $uId = $chUser->related("profiles.user")->fetch()->id; - $user = (new Users)->get($uId); + $user = (new Users())->get($uId); $code = $this->requestParam("code"); - if($user->is2faEnabled() && !($code === (new Totp)->GenerateToken(Base32::decode($user->get2faSecret())) || $user->use2faBackupCode((int) $code))) { - if($this->requestParam("2fa_supported") == "1") + if ($user->is2faEnabled() && !($code === (new Totp())->GenerateToken(Base32::decode($user->get2faSecret())) || $user->use2faBackupCode((int) $code))) { + if ($this->requestParam("2fa_supported") == "1") { $this->twofaFail($user->getId()); - else + } else { $this->fail(28, "Invalid 2FA code", "internal", "acquireToken"); + } } - - $token = NULL; + + $token = null; $tokenIsStale = true; $platform = $this->requestParam("client_name"); $acceptsStale = $this->requestParam("accepts_stale"); - if($acceptsStale == "1") { - if(is_null($platform)) + if ($acceptsStale == "1") { + if (is_null($platform)) { $this->fail(101, "accepts_stale can only be used with explicitly set client_name", "internal", "acquireToken"); - - $token = (new APITokens)->getStaleByUser($uId, $platform); + } + + $token = (new APITokens())->getStaleByUser($uId, $platform); } - - if(is_null($token)) { + + if (is_null($token)) { $tokenIsStale = false; - - $token = new APIToken; + + $token = new APIToken(); $token->setUser($user); $token->setPlatform($platform ?? (new WhichBrowser\Parser(getallheaders()))->toString()); $token->save(); } - + $payload = json_encode([ "access_token" => $token->getFormattedToken(), "expires_in" => 0, @@ -346,44 +367,49 @@ final class VKAPIPresenter extends OpenVKPresenter "is_stale" => $tokenIsStale, "secret" => "super_secret_value", ]); - + $size = strlen($payload); header("Content-Type: application/json"); header("Content-Length: $size"); exit($payload); } - - function renderOAuthLogin() { + + public function renderOAuthLogin() + { $this->assertUserLoggedIn(); - + $client = $this->queryParam("client_name"); $postmsg = $this->queryParam("prefers_postMessage") ?? '0'; $stale = $this->queryParam("accepts_stale") ?? '0'; - $origin = NULL; + $origin = null; $url = $this->queryParam("redirect_uri"); - if(is_null($url) || is_null($client)) + if (is_null($url) || is_null($client)) { exit("Error: redirect_uri and client_name params are required."); - - if($url != "about:blank") { - if(!filter_var($url, FILTER_VALIDATE_URL)) + } + + if ($url != "about:blank") { + if (!filter_var($url, FILTER_VALIDATE_URL)) { exit("Error: Invalid URL passed to redirect_uri."); - + } + $parsedUrl = (object) parse_url($url); - if($parsedUrl->scheme != 'https' && $parsedUrl->scheme != 'http') + if ($parsedUrl->scheme != 'https' && $parsedUrl->scheme != 'http') { exit("Error: redirect_uri should either point to about:blank or to a web resource."); - + } + $origin = "$parsedUrl->scheme://$parsedUrl->host"; - if(!is_null($parsedUrl->port ?? NULL)) + if (!is_null($parsedUrl->port ?? null)) { $origin .= ":$parsedUrl->port"; - + } + $url .= strpos($url, '?') === false ? '?' : '&'; } else { $url .= "#"; - if($postmsg == '1') { + if ($postmsg == '1') { exit("Error: prefers_postMessage can only be set if redirect_uri is not about:blank"); } } - + $this->template->clientName = $client; $this->template->usePostMessage = $postmsg == '1'; $this->template->acceptsStale = $stale == '1'; diff --git a/Web/Presenters/VideosPresenter.php b/Web/Presenters/VideosPresenter.php index dbf4efea..e2e1a6f4 100644 --- a/Web/Presenters/VideosPresenter.php +++ b/Web/Presenters/VideosPresenter.php @@ -1,5 +1,9 @@ -videos = $videos; $this->users = $users; - + parent::__construct(); } - - function renderList(int $id): void + + public function renderList(int $id): void { $user = $this->users->get($id); - if(!$user) $this->notFound(); - if(!$user->getPrivacyPermission('videos.read', $this->user->identity ?? NULL)) + if (!$user) { + $this->notFound(); + } + if (!$user->getPrivacyPermission('videos.read', $this->user->identity ?? null)) { $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); - + } + $this->template->user = $user; $this->template->videos = $this->videos->getByUser($user, (int) ($this->queryParam("p") ?? 1)); $this->template->count = $this->videos->getUserVideosCount($user); $this->template->paginatorConf = (object) [ "count" => $this->template->count, "page" => (int) ($this->queryParam("p") ?? 1), - "amount" => NULL, + "amount" => null, "perPage" => 7, ]; } - - function renderView(int $owner, int $vId): void + + public function renderView(int $owner, int $vId): void { $user = $this->users->get($owner); $video = $this->videos->getByOwnerAndVID($owner, $vId); - if(!$user) $this->notFound(); - if(!$video || $video->isDeleted()) $this->notFound(); - if(!$user->getPrivacyPermission('videos.read', $this->user->identity ?? NULL)) + if (!$user) { + $this->notFound(); + } + if (!$video || $video->isDeleted()) { + $this->notFound(); + } + if (!$user->getPrivacyPermission('videos.read', $this->user->identity ?? null)) { $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); - + } + $this->template->user = $user; $this->template->video = $this->videos->getByOwnerAndVID($owner, $vId); $this->template->cCount = $this->template->video->getCommentsCount(); $this->template->cPage = (int) ($this->queryParam("p") ?? 1); $this->template->comments = iterator_to_array($this->template->video->getComments($this->template->cPage)); } - - function renderUpload(): void + + public function renderUpload(): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - if(OPENVK_ROOT_CONF['openvk']['preferences']['videos']['disableUploading']) + if (OPENVK_ROOT_CONF['openvk']['preferences']['videos']['disableUploading']) { $this->flashFail("err", tr("error"), tr("video_uploads_disabled")); - - if($_SERVER["REQUEST_METHOD"] === "POST") { - $is_ajax = (int)($this->postParam('ajax') ?? '0') == 1; - if(!empty($this->postParam("name"))) { - $video = new Video; + } + + if ($_SERVER["REQUEST_METHOD"] === "POST") { + $is_ajax = (int) ($this->postParam('ajax') ?? '0') == 1; + if (!empty($this->postParam("name"))) { + $video = new Video(); $video->setOwner($this->user->id); $video->setName(ovk_proc_strtr($this->postParam("name"), 61)); $video->setDescription(ovk_proc_strtr($this->postParam("desc"), 300)); $video->setCreated(time()); - + try { - if(isset($_FILES["blob"]) && file_exists($_FILES["blob"]["tmp_name"])) + if (isset($_FILES["blob"]) && file_exists($_FILES["blob"]["tmp_name"])) { $video->setFile($_FILES["blob"]); - else if(!empty($this->postParam("link"))) + } elseif (!empty($this->postParam("link"))) { $video->setLink($this->postParam("link")); - else + } else { $this->flashFail("err", tr("no_video_error"), tr("no_video_description"), 10, $is_ajax); - } catch(\DomainException $ex) { + } + } catch (\DomainException $ex) { $this->flashFail("err", tr("error_video"), tr("file_corrupted"), 10, $is_ajax); - } catch(ISE $ex) { + } catch (ISE $ex) { $this->flashFail("err", tr("error_video"), tr("link_incorrect"), 10, $is_ajax); } - - if((int)($this->postParam("unlisted") ?? '0') == 1) { + + if ((int) ($this->postParam("unlisted") ?? '0') == 1) { $video->setUnlisted(true); } $video->save(); - - if($is_ajax) { + + if ($is_ajax) { $object = $video->getApiStructure(); $this->returnJson([ 'payload' => $object->video, @@ -102,74 +116,79 @@ final class VideosPresenter extends OpenVKPresenter } } } - - function renderEdit(int $owner, int $vId): void + + public function renderEdit(int $owner, int $vId): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - + $video = $this->videos->getByOwnerAndVID($owner, $vId); - if(!$video) + if (!$video) { $this->notFound(); - if(is_null($this->user) || $this->user->id !== $owner) + } + if (is_null($this->user) || $this->user->id !== $owner) { $this->flashFail("err", tr("access_denied_error"), tr("access_denied_error_description")); - - if($_SERVER["REQUEST_METHOD"] === "POST") { - $video->setName(empty($this->postParam("name")) ? NULL : $this->postParam("name")); - $video->setDescription(empty($this->postParam("desc")) ? NULL : $this->postParam("desc")); + } + + if ($_SERVER["REQUEST_METHOD"] === "POST") { + $video->setName(empty($this->postParam("name")) ? null : $this->postParam("name")); + $video->setDescription(empty($this->postParam("desc")) ? null : $this->postParam("desc")); $video->save(); - + $this->flash("succ", tr("changes_saved"), tr("changes_saved_video_comment")); $this->redirect("/video" . $video->getPrettyId()); - } - + } + $this->template->video = $video; } - function renderRemove(int $owner, int $vid): void + public function renderRemove(int $owner, int $vid): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - + $video = $this->videos->getByOwnerAndVID($owner, $vid); - if(!$video) + if (!$video) { $this->notFound(); + } $user = $this->user->id; - - if(!is_null($user)) { - if($video->getOwnerVideo() == $user) { + + if (!is_null($user)) { + if ($video->getOwnerVideo() == $user) { $video->deleteVideo($owner, $vid); } } else { $this->flashFail("err", tr("cant_delete_video"), tr("cant_delete_video_comment")); } - + $this->redirect("/videos" . $owner); } - function renderLike(int $owner, int $video_id): void + public function renderLike(int $owner, int $video_id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); $this->assertNoCSRF(); $video = $this->videos->getByOwnerAndVID($owner, $video_id); - if(!$video || $video->isDeleted() || $video->getOwner()->isDeleted()) $this->notFound(); + if (!$video || $video->isDeleted() || $video->getOwner()->isDeleted()) { + $this->notFound(); + } - if(method_exists($video, "canBeViewedBy") && !$video->canBeViewedBy($this->user->identity)) { + if (method_exists($video, "canBeViewedBy") && !$video->canBeViewedBy($this->user->identity)) { $this->flashFail("err", tr("error"), tr("forbidden")); } - if(!is_null($this->user)) { + if (!is_null($this->user)) { $video->toggleLike($this->user->identity); } - - if($_SERVER["REQUEST_METHOD"] === "POST") { + + if ($_SERVER["REQUEST_METHOD"] === "POST") { $this->returnJson([ 'success' => true, ]); } - + $this->redirect("$_SERVER[HTTP_REFERER]"); } } diff --git a/Web/Presenters/WallPresenter.php b/Web/Presenters/WallPresenter.php index 285ee37a..b64c2af9 100644 --- a/Web/Presenters/WallPresenter.php +++ b/Web/Presenters/WallPresenter.php @@ -1,5 +1,9 @@ -posts = $posts; - + parent::__construct(); } - + private function logPostView(Post $post, int $wall): void { - if(is_null($this->user)) + if (is_null($this->user)) { return; - + } + $this->logEvent("postView", [ "profile" => $this->user->identity->getId(), "post" => $post->getId(), @@ -34,47 +39,54 @@ final class WallPresenter extends OpenVKPresenter "subscribed" => $wall < 0 ? $post->getOwner()->getSubscriptionStatus($this->user->identity) : false, ]); } - + private function logPostsViewed(array &$posts, int $wall): void { $x = array_values($posts); # clone array (otherwise Nette DB objects will become kinda gay) - - foreach($x as $post) + + foreach ($x as $post) { $this->logPostView($post, $wall); + } } - - function renderWall(int $user, bool $embedded = false): void + + public function renderWall(int $user, bool $embedded = false): void { - $owner = ($user < 0 ? (new Clubs) : (new Users))->get(abs($user)); - if ($owner->isBanned() || !$owner->canBeViewedBy($this->user->identity)) + $owner = ($user < 0 ? (new Clubs()) : (new Users()))->get(abs($user)); + if ($owner->isBanned() || !$owner->canBeViewedBy($this->user->identity)) { $this->flashFail("err", tr("error"), tr("forbidden")); + } - if ($user > 0 && $owner->isDeleted()) + if ($user > 0 && $owner->isDeleted()) { $this->flashFail("err", tr("error"), tr("forbidden")); + } - if(is_null($this->user)) { + if (is_null($this->user)) { $canPost = false; - } else if($user > 0) { + } elseif ($user > 0) { $canPost = $owner->getPrivacyPermission("wall.write", $this->user->identity); - } else if($user < 0) { - if($owner->canBeModifiedBy($this->user->identity)) + } elseif ($user < 0) { + if ($owner->canBeModifiedBy($this->user->identity)) { $canPost = true; - else + } else { $canPost = $owner->canPost(); + } } else { $canPost = false; } - - if ($embedded == true) $this->template->_template = "components/wall.xml"; - $this->template->oObj = $owner; - if($user < 0) - $this->template->club = $owner; - $iterator = NULL; + if ($embedded == true) { + $this->template->_template = "components/wall.xml"; + } + $this->template->oObj = $owner; + if ($user < 0) { + $this->template->club = $owner; + } + + $iterator = null; $count = 0; $type = $this->queryParam("type") ?? "all"; - switch($type) { + switch ($type) { default: case "all": $iterator = $this->posts->getPostsFromUsersWall($user, (int) ($_GET["p"] ?? 1)); @@ -89,7 +101,7 @@ final class WallPresenter extends OpenVKPresenter $count = $this->posts->getOthersCountOnUserWall($user); break; } - + $this->template->owner = $user; $this->template->canPost = $canPost; $this->template->count = $count; @@ -102,32 +114,34 @@ final class WallPresenter extends OpenVKPresenter "perPage" => OPENVK_DEFAULT_PER_PAGE, ]; - + $this->logPostsViewed($this->template->posts, $user); } - function renderWallEmbedded(int $user): void + public function renderWallEmbedded(int $user): void { $this->renderWall($user, true); } - function renderRSS(int $user): void + public function renderRSS(int $user): void { - $owner = ($user < 0 ? (new Clubs) : (new Users))->get(abs($user)); - if(is_null($this->user)) { + $owner = ($user < 0 ? (new Clubs()) : (new Users()))->get(abs($user)); + if (is_null($this->user)) { $canPost = false; - } else if($user > 0) { - if(!$owner->isBanned() && $owner->canBeViewedBy($this->user->identity)) + } elseif ($user > 0) { + if (!$owner->isBanned() && $owner->canBeViewedBy($this->user->identity)) { $canPost = $owner->getPrivacyPermission("wall.write", $this->user->identity); - else + } else { $this->flashFail("err", tr("error"), tr("forbidden")); - } else if($user < 0) { - if($owner->canBeModifiedBy($this->user->identity)) + } + } elseif ($user < 0) { + if ($owner->canBeModifiedBy($this->user->identity)) { $canPost = true; - else if ($owner->isBanned()) + } elseif ($owner->isBanned()) { $this->flashFail("err", tr("error"), tr("forbidden")); - else + } else { $canPost = $owner->canPost(); + } } else { $canPost = false; } @@ -139,12 +153,12 @@ final class WallPresenter extends OpenVKPresenter $channel = new Channel(); $channel->title($owner->getCanonicalName() . " — " . OPENVK_ROOT_CONF['openvk']['appearance']['name'])->url(ovk_scheme(true) . $_SERVER["HTTP_HOST"])->appendTo($feed); - foreach($posts as $post) { + foreach ($posts as $post) { $item = new Item(); $item ->title($post->getOwner()->getCanonicalName()) ->description($post->getText()) - ->url(ovk_scheme(true).$_SERVER["HTTP_HOST"]."/wall{$post->getPrettyId()}") + ->url(ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/wall{$post->getPrettyId()}") ->pubDate($post->getPublicationTime()->timestamp()) ->appendTo($channel); } @@ -152,21 +166,21 @@ final class WallPresenter extends OpenVKPresenter header("Content-Type: application/rss+xml"); exit($feed); } - - function renderFeed(): void + + public function renderFeed(): void { $this->assertUserLoggedIn(); - + $id = $this->user->id; $subs = DatabaseConnection::i() ->getContext() ->table("subscriptions") ->where("follower", $id); - $ids = array_map(function($rel) { + $ids = array_map(function ($rel) { return $rel->target * ($rel->model === "openvk\Web\Models\Entities\User" ? 1 : -1); }, iterator_to_array($subs)); $ids[] = $this->user->id; - + $perPage = min((int) ($_GET["posts"] ?? OPENVK_DEFAULT_PER_PAGE), 50); $posts = DatabaseConnection::i() ->getContext() @@ -183,36 +197,38 @@ final class WallPresenter extends OpenVKPresenter "perPage" => $perPage, ]; $this->template->posts = []; - foreach($posts->page((int) ($_GET["p"] ?? 1), $perPage) as $post) + foreach ($posts->page((int) ($_GET["p"] ?? 1), $perPage) as $post) { $this->template->posts[] = $this->posts->get($post->id); + } } - - function renderGlobalFeed(): void + + public function renderGlobalFeed(): void { $this->assertUserLoggedIn(); - + $page = (int) ($_GET["p"] ?? 1); $pPage = min((int) ($_GET["posts"] ?? OPENVK_DEFAULT_PER_PAGE), 50); - + $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($this->user->identity->getNsfwTolerance() === User::NSFW_INTOLERANT) + if ($this->user->identity->getNsfwTolerance() === User::NSFW_INTOLERANT) { $queryBase .= " AND `nsfw` = 0"; + } - if(((int)$this->queryParam('return_banned')) == 0) { + if (((int) $this->queryParam('return_banned')) == 0) { $ignored_sources_ids = $this->user->identity->getIgnoredSources(0, OPENVK_ROOT_CONF['openvk']['preferences']['newsfeed']['ignoredSourcesLimit'] ?? 50, true); - - if(sizeof($ignored_sources_ids) > 0) { + + if (sizeof($ignored_sources_ids) > 0) { $imploded_ids = implode("', '", $ignored_sources_ids); - + $queryBase .= " AND `posts`.`wall` NOT IN ('$imploded_ids')"; } } $posts = DatabaseConnection::i()->getConnection()->query("SELECT `posts`.`id` " . $queryBase . " ORDER BY `created` DESC LIMIT " . $pPage . " OFFSET " . ($page - 1) * $pPage); $count = DatabaseConnection::i()->getConnection()->query("SELECT COUNT(*) " . $queryBase)->fetch()->{"COUNT(*)"}; - + $this->template->_template = "Wall/Feed.xml"; $this->template->globalFeed = true; $this->template->paginatorConf = (object) [ @@ -221,18 +237,19 @@ final class WallPresenter extends OpenVKPresenter "amount" => $posts->getRowCount(), "perPage" => $pPage, ]; - foreach($posts as $post) + foreach ($posts as $post) { $this->template->posts[] = $this->posts->get($post->id); + } } - - function renderHashtagFeed(string $hashtag): void + + public function renderHashtagFeed(string $hashtag): void { $hashtag = rawurldecode($hashtag); - + $page = (int) ($_GET["p"] ?? 1); $posts = $this->posts->getPostsByHashtag($hashtag, $page); $count = $this->posts->getPostCountByHashtag($hashtag); - + $this->template->hashtag = $hashtag; $this->template->posts = $posts; $this->template->paginatorConf = (object) [ @@ -242,95 +259,103 @@ final class WallPresenter extends OpenVKPresenter "perPage" => OPENVK_DEFAULT_PER_PAGE, ]; } - - function renderMakePost(int $wall): void + + public function renderMakePost(int $wall): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - - $wallOwner = ($wall > 0 ? (new Users)->get($wall) : (new Clubs)->get($wall * -1)) + + $wallOwner = ($wall > 0 ? (new Users())->get($wall) : (new Clubs())->get($wall * -1)) ?? $this->flashFail("err", tr("failed_to_publish_post"), tr("error_4")); - if ($wallOwner->isBanned()) + if ($wallOwner->isBanned()) { $this->flashFail("err", tr("error"), tr("forbidden")); - - if($wall > 0) { - $canPost = $wallOwner->getPrivacyPermission("wall.write", $this->user->identity); - } else if($wall < 0) { - if($wallOwner->canBeModifiedBy($this->user->identity)) - $canPost = true; - else - $canPost = $wallOwner->canPost(); - } else { - $canPost = false; } - - if(!$canPost) + + if ($wall > 0) { + $canPost = $wallOwner->getPrivacyPermission("wall.write", $this->user->identity); + } elseif ($wall < 0) { + if ($wallOwner->canBeModifiedBy($this->user->identity)) { + $canPost = true; + } else { + $canPost = $wallOwner->canPost(); + } + } else { + $canPost = false; + } + + if (!$canPost) { $this->flashFail("err", tr("not_enough_permissions"), tr("not_enough_permissions_comment")); - + } + $anon = OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["enable"]; - if($wallOwner instanceof Club && $this->postParam("as_group") === "on" && $this->postParam("force_sign") !== "on" && $anon) { + if ($wallOwner instanceof Club && $this->postParam("as_group") === "on" && $this->postParam("force_sign") !== "on" && $anon) { $manager = $wallOwner->getManager($this->user->identity); - if($manager) + if ($manager) { $anon = $manager->isHidden(); - elseif($this->user->identity->getId() === $wallOwner->getOwner()->getId()) + } elseif ($this->user->identity->getId() === $wallOwner->getOwner()->getId()) { $anon = $wallOwner->isOwnerHidden(); + } } else { $anon = $anon && $this->postParam("anon") === "on"; } - + $flags = 0; - if($this->postParam("as_group") === "on" && $wallOwner instanceof Club && $wallOwner->canBeModifiedBy($this->user->identity)) + if ($this->postParam("as_group") === "on" && $wallOwner instanceof Club && $wallOwner->canBeModifiedBy($this->user->identity)) { $flags |= 0b10000000; - if($this->postParam("force_sign") === "on") + } + if ($this->postParam("force_sign") === "on") { $flags |= 0b01000000; - + } + $horizontal_attachments = []; $vertical_attachments = []; - if(!empty($this->postParam("horizontal_attachments"))) { + if (!empty($this->postParam("horizontal_attachments"))) { $horizontal_attachments_array = array_slice(explode(",", $this->postParam("horizontal_attachments")), 0, OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["maxAttachments"]); - if(sizeof($horizontal_attachments_array) > 0) { + if (sizeof($horizontal_attachments_array) > 0) { $horizontal_attachments = parseAttachments($horizontal_attachments_array, ['photo', 'video']); } } - if(!empty($this->postParam("vertical_attachments"))) { + if (!empty($this->postParam("vertical_attachments"))) { $vertical_attachments_array = array_slice(explode(",", $this->postParam("vertical_attachments")), 0, OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["maxAttachments"]); - if(sizeof($vertical_attachments_array) > 0) { + if (sizeof($vertical_attachments_array) > 0) { $vertical_attachments = parseAttachments($vertical_attachments_array, ['audio', 'note', 'doc']); } } try { - $poll = NULL; + $poll = null; $xml = $this->postParam("poll"); - if (!is_null($xml) && $xml != "none") + if (!is_null($xml) && $xml != "none") { $poll = Poll::import($this->user->identity, $xml); - } catch(TooMuchOptionsException $e) { + } + } catch (TooMuchOptionsException $e) { $this->flashFail("err", tr("failed_to_publish_post"), tr("poll_err_to_much_options")); - } catch(\UnexpectedValueException $e) { + } catch (\UnexpectedValueException $e) { $this->flashFail("err", tr("failed_to_publish_post"), "Poll format invalid"); } - $geo = NULL; + $geo = null; if (!is_null($this->postParam("geo")) && $this->postParam("geo") != "") { $geo = json_decode($this->postParam("geo"), true, JSON_UNESCAPED_UNICODE); - if($geo["lat"] && $geo["lng"] && $geo["name"]) { + if ($geo["lat"] && $geo["lng"] && $geo["name"]) { $latitude = number_format((float) $geo["lat"], 8, ".", ''); $longitude = number_format((float) $geo["lng"], 8, ".", ''); - if($latitude > 90 || $latitude < -90 || $longitude > 180 || $longitude < -180) { + if ($latitude > 90 || $latitude < -90 || $longitude > 180 || $longitude < -180) { $this->flashFail("err", tr("error"), "Invalid latitude or longitude"); } } } - - if(empty($this->postParam("text")) && sizeof($horizontal_attachments) < 1 && sizeof($vertical_attachments) < 1 && !$poll) + + if (empty($this->postParam("text")) && sizeof($horizontal_attachments) < 1 && sizeof($vertical_attachments) < 1 && !$poll) { $this->flashFail("err", tr("failed_to_publish_post"), tr("post_is_empty_or_too_big")); - + } + $should_be_suggested = $wall < 0 && !$wallOwner->canBeModifiedBy($this->user->identity) && $wallOwner->getWallType() == 2; try { - $post = new Post; + $post = new Post(); $post->setOwner($this->user->id); $post->setWall($wall); $post->setCreated(time()); @@ -339,15 +364,17 @@ final class WallPresenter extends OpenVKPresenter $post->setFlags($flags); $post->setNsfw($this->postParam("nsfw") === "on"); - if(!empty($this->postParam("source")) && $this->postParam("source") != 'none') { + if (!empty($this->postParam("source")) && $this->postParam("source") != 'none') { try { $post->setSource($this->postParam("source")); - } catch(\Throwable) {} + } catch (\Throwable) { + } } - if($should_be_suggested) + if ($should_be_suggested) { $post->setSuggested(1); - + } + if ($geo) { $post->setGeo($geo); $post->setGeo_Lat($latitude); @@ -357,142 +384,160 @@ final class WallPresenter extends OpenVKPresenter } catch (\LengthException $ex) { $this->flashFail("err", tr("failed_to_publish_post"), tr("post_is_too_big")); } - - foreach($horizontal_attachments as $horizontal_attachment) { - if(!$horizontal_attachment || $horizontal_attachment->isDeleted() || !$horizontal_attachment->canBeViewedBy($this->user->identity)) { + + foreach ($horizontal_attachments as $horizontal_attachment) { + if (!$horizontal_attachment || $horizontal_attachment->isDeleted() || !$horizontal_attachment->canBeViewedBy($this->user->identity)) { continue; } $post->attach($horizontal_attachment); } - foreach($vertical_attachments as $vertical_attachment) { - if(!$vertical_attachment || $vertical_attachment->isDeleted() || !$vertical_attachment->canBeViewedBy($this->user->identity)) { + foreach ($vertical_attachments as $vertical_attachment) { + if (!$vertical_attachment || $vertical_attachment->isDeleted() || !$vertical_attachment->canBeViewedBy($this->user->identity)) { continue; } $post->attach($vertical_attachment); } - - if(!is_null($poll)) - $post->attach($poll); - - if($wall > 0 && $wall !== $this->user->identity->getId()) - (new WallPostNotification($wallOwner, $post, $this->user->identity))->emit(); - - $excludeMentions = [$this->user->identity->getId()]; - if($wall > 0) - $excludeMentions[] = $wall; - if(!$should_be_suggested) { + if (!is_null($poll)) { + $post->attach($poll); + } + + if ($wall > 0 && $wall !== $this->user->identity->getId()) { + (new WallPostNotification($wallOwner, $post, $this->user->identity))->emit(); + } + + $excludeMentions = [$this->user->identity->getId()]; + if ($wall > 0) { + $excludeMentions[] = $wall; + } + + if (!$should_be_suggested) { $mentions = iterator_to_array($post->resolveMentions($excludeMentions)); - foreach($mentions as $mentionee) - if($mentionee instanceof User) + foreach ($mentions as $mentionee) { + if ($mentionee instanceof User) { (new MentionNotification($mentionee, $post, $post->getOwner(), strip_tags($post->getText())))->emit(); + } + } } - - if($should_be_suggested) { - $this->redirect("/club".$wallOwner->getId()."/suggested"); + + if ($should_be_suggested) { + $this->redirect("/club" . $wallOwner->getId() . "/suggested"); } else { $this->redirect($wallOwner->getURL()); } } - - function renderPost(int $wall, int $post_id): void + + public function renderPost(int $wall, int $post_id): void { $post = $this->posts->getPostById($wall, $post_id); - if(!$post || $post->isDeleted()) + if (!$post || $post->isDeleted()) { $this->notFound(); + } - if(!$post->canBeViewedBy($this->user->identity)) + if (!$post->canBeViewedBy($this->user->identity)) { $this->flashFail("err", tr("error"), tr("forbidden")); - + } + $this->logPostView($post, $wall); - + $this->template->post = $post; if ($post->getTargetWall() > 0) { - $this->template->wallOwner = (new Users)->get($post->getTargetWall()); + $this->template->wallOwner = (new Users())->get($post->getTargetWall()); $this->template->isWallOfGroup = false; - if($this->template->wallOwner->isBanned()) + if ($this->template->wallOwner->isBanned()) { $this->flashFail("err", tr("error"), tr("forbidden")); + } } else { - $this->template->wallOwner = (new Clubs)->get(abs($post->getTargetWall())); + $this->template->wallOwner = (new Clubs())->get(abs($post->getTargetWall())); $this->template->isWallOfGroup = true; - if ($this->template->wallOwner->isBanned()) + if ($this->template->wallOwner->isBanned()) { $this->flashFail("err", tr("error"), tr("forbidden")); + } } $this->template->cCount = $post->getCommentsCount(); $this->template->cPage = (int) ($_GET["p"] ?? 1); $this->template->comments = iterator_to_array($post->getComments($this->template->cPage)); } - - function renderLike(int $wall, int $post_id): void + + public function renderLike(int $wall, int $post_id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); $this->assertNoCSRF(); - + $post = $this->posts->getPostById($wall, $post_id); - if(!$post || $post->isDeleted()) $this->notFound(); + if (!$post || $post->isDeleted()) { + $this->notFound(); + } - if ($post->getWallOwner()->isBanned()) + if ($post->getWallOwner()->isBanned()) { $this->flashFail("err", tr("error"), tr("forbidden")); + } - if(!is_null($this->user)) { + if (!is_null($this->user)) { $post->toggleLike($this->user->identity); } - if($_SERVER["REQUEST_METHOD"] === "POST") { + if ($_SERVER["REQUEST_METHOD"] === "POST") { $this->returnJson([ 'success' => true, ]); } - + $this->redirect("$_SERVER[HTTP_REFERER]#postGarter=" . $post->getId()); } - - function renderShare(int $wall, int $post_id): void + + public function renderShare(int $wall, int $post_id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); $this->assertNoCSRF(); - + $post = $this->posts->getPostById($wall, $post_id); - if(!$post || $post->isDeleted()) + if (!$post || $post->isDeleted()) { $this->notFound(); + } - if ($post->getWallOwner()->isBanned()) + if ($post->getWallOwner()->isBanned()) { $this->flashFail("err", tr("error"), tr("forbidden")); - + } + $where = $this->postParam("type") ?? "wall"; - $groupId = NULL; + $groupId = null; $flags = 0; - if($where == "group") + if ($where == "group") { $groupId = $this->postParam("groupId"); + } - if(!is_null($this->user)) { - $nPost = new Post; + if (!is_null($this->user)) { + $nPost = new Post(); - if($where == "wall") { + if ($where == "wall") { $nPost->setOwner($this->user->id); $nPost->setWall($this->user->id); - } elseif($where == "group") { + } elseif ($where == "group") { $nPost->setOwner($this->user->id); - $club = (new Clubs)->get((int)$groupId); + $club = (new Clubs())->get((int) $groupId); - if(!$club || !$club->canBeModifiedBy($this->user->identity)) + if (!$club || !$club->canBeModifiedBy($this->user->identity)) { $this->notFound(); - - if($this->postParam("asGroup") == 1) - $flags |= 0b10000000; + } - if($this->postParam("signed") == 1) + if ($this->postParam("asGroup") == 1) { + $flags |= 0b10000000; + } + + if ($this->postParam("signed") == 1) { $flags |= 0b01000000; - + } + $nPost->setWall($groupId * -1); } @@ -501,80 +546,91 @@ final class WallPresenter extends OpenVKPresenter $nPost->save(); $nPost->attach($post); - - if($post->getOwner(false)->getId() !== $this->user->identity->getId() && !($post->getOwner() instanceof Club)) + + if ($post->getOwner(false)->getId() !== $this->user->identity->getId() && !($post->getOwner() instanceof Club)) { (new RepostNotification($post->getOwner(false), $post, $this->user->identity))->emit(); + } }; - + $this->returnJson([ - "wall_owner" => $where == "wall" ? $this->user->identity->getId() : $groupId * -1 + "wall_owner" => $where == "wall" ? $this->user->identity->getId() : $groupId * -1, ]); } - - function renderDelete(int $wall, int $post_id): void + + public function renderDelete(int $wall, int $post_id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - + $post = $this->posts->getPostById($wall, $post_id, true); - if(!$post) + if (!$post) { $this->notFound(); + } $user = $this->user->id; - $wallOwner = ($wall > 0 ? (new Users)->get($wall) : (new Clubs)->get($wall * -1)) + $wallOwner = ($wall > 0 ? (new Users())->get($wall) : (new Clubs())->get($wall * -1)) ?? $this->flashFail("err", tr("failed_to_delete_post"), tr("error_4")); - if ($wallOwner->isBanned()) + if ($wallOwner->isBanned()) { $this->flashFail("err", tr("error"), tr("forbidden")); + } - if($wall < 0) $canBeDeletedByOtherUser = $wallOwner->canBeModifiedBy($this->user->identity); - else $canBeDeletedByOtherUser = false; + if ($wall < 0) { + $canBeDeletedByOtherUser = $wallOwner->canBeModifiedBy($this->user->identity); + } else { + $canBeDeletedByOtherUser = false; + } - if(!is_null($user)) { - if($post->getTargetWall() < 0 && !$post->getWallOwner()->canBeModifiedBy($this->user->identity) && $post->getWallOwner()->getWallType() != 1 && $post->getSuggestionType() == 0) + if (!is_null($user)) { + if ($post->getTargetWall() < 0 && !$post->getWallOwner()->canBeModifiedBy($this->user->identity) && $post->getWallOwner()->getWallType() != 1 && $post->getSuggestionType() == 0) { $this->flashFail("err", tr("failed_to_delete_post"), tr("error_deleting_suggested")); - - if($post->getOwnerPost() == $user || $post->getTargetWall() == $user || $canBeDeletedByOtherUser) { + } + + if ($post->getOwnerPost() == $user || $post->getTargetWall() == $user || $canBeDeletedByOtherUser) { $post->unwire(); $post->delete(); } } else { $this->flashFail("err", tr("failed_to_delete_post"), tr("login_required_error_comment")); } - - $this->redirect($wall < 0 ? "/club" . ($wall*-1) : "/id" . $wall); + + $this->redirect($wall < 0 ? "/club" . ($wall * -1) : "/id" . $wall); } - - function renderPin(int $wall, int $post_id): void + + public function renderPin(int $wall, int $post_id): void { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - - $post = $this->posts->getPostById($wall, $post_id); - if(!$post) - $this->notFound(); - if ($post->getWallOwner()->isBanned()) + $post = $this->posts->getPostById($wall, $post_id); + if (!$post) { + $this->notFound(); + } + + if ($post->getWallOwner()->isBanned()) { $this->flashFail("err", tr("error"), tr("forbidden")); - - if(!$post->canBePinnedBy($this->user->identity)) + } + + if (!$post->canBePinnedBy($this->user->identity)) { $this->flashFail("err", tr("not_enough_permissions"), tr("not_enough_permissions_comment")); - - if(($this->queryParam("act") ?? "pin") === "pin") { + } + + if (($this->queryParam("act") ?? "pin") === "pin") { $post->pin(); } else { $post->unpin(); } - + # TODO localize message based on language and ?act=(un)pin $this->flashFail("succ", tr("information_-1"), tr("changes_saved_comment")); } - function renderAccept() { + public function renderAccept() + { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(true); - if($_SERVER["REQUEST_METHOD"] !== "POST") { + if ($_SERVER["REQUEST_METHOD"] !== "POST") { header("HTTP/1.1 405 Method Not Allowed"); exit("Ты дебил, это точка апи."); } @@ -583,71 +639,83 @@ final class WallPresenter extends OpenVKPresenter $sign = $this->postParam("sign") == 1; $content = $this->postParam("new_content"); - $post = (new Posts)->get((int)$id); + $post = (new Posts())->get((int) $id); - if(!$post || $post->isDeleted()) - $this->flashFail("err", "Error", tr("error_accepting_invalid_post"), NULL, true); + if (!$post || $post->isDeleted()) { + $this->flashFail("err", "Error", tr("error_accepting_invalid_post"), null, true); + } - if($post->getSuggestionType() == 0) - $this->flashFail("err", "Error", tr("error_accepting_not_suggested_post"), NULL, true); + if ($post->getSuggestionType() == 0) { + $this->flashFail("err", "Error", tr("error_accepting_not_suggested_post"), null, true); + } - if($post->getSuggestionType() == 2) - $this->flashFail("err", "Error", tr("error_accepting_declined_post"), NULL, true); + if ($post->getSuggestionType() == 2) { + $this->flashFail("err", "Error", tr("error_accepting_declined_post"), null, true); + } - if(!$post->canBePinnedBy($this->user->identity)) - $this->flashFail("err", "Error", "Can't accept this post.", NULL, true); + if (!$post->canBePinnedBy($this->user->identity)) { + $this->flashFail("err", "Error", "Can't accept this post.", null, true); + } $author = $post->getOwner(); $flags = 0; $flags |= 0b10000000; - if($sign) + if ($sign) { $flags |= 0b01000000; + } $post->setSuggested(0); $post->setCreated(time()); - $post->setApi_Source_Name(NULL); + $post->setApi_Source_Name(null); $post->setFlags($flags); - - if(mb_strlen($content) > 0) + + if (mb_strlen($content) > 0) { $post->setContent($content); - + } + $post->save(); - if($author->getId() != $this->user->id) + if ($author->getId() != $this->user->id) { (new PostAcceptedNotification($author, $post, $post->getWallOwner()))->emit(); + } $this->returnJson([ "success" => true, "id" => $post->getPrettyId(), - "new_count" => (new Posts)->getSuggestedPostsCount($post->getWallOwner()->getId()) + "new_count" => (new Posts())->getSuggestedPostsCount($post->getWallOwner()->getId()), ]); } - function renderDecline() { + public function renderDecline() + { $this->assertUserLoggedIn(); $this->willExecuteWriteAction(true); - if($_SERVER["REQUEST_METHOD"] !== "POST") { + if ($_SERVER["REQUEST_METHOD"] !== "POST") { header("HTTP/1.1 405 Method Not Allowed"); exit("Ты дебил, это метод апи."); } $id = $this->postParam("id"); - $post = (new Posts)->get((int)$id); + $post = (new Posts())->get((int) $id); - if(!$post || $post->isDeleted()) - $this->flashFail("err", "Error", tr("error_declining_invalid_post"), NULL, true); + if (!$post || $post->isDeleted()) { + $this->flashFail("err", "Error", tr("error_declining_invalid_post"), null, true); + } - if($post->getSuggestionType() == 0) - $this->flashFail("err", "Error", tr("error_declining_not_suggested_post"), NULL, true); + if ($post->getSuggestionType() == 0) { + $this->flashFail("err", "Error", tr("error_declining_not_suggested_post"), null, true); + } - if($post->getSuggestionType() == 2) - $this->flashFail("err", "Error", tr("error_declining_declined_post"), NULL, true); + if ($post->getSuggestionType() == 2) { + $this->flashFail("err", "Error", tr("error_declining_declined_post"), null, true); + } - if(!$post->canBePinnedBy($this->user->identity)) - $this->flashFail("err", "Error", "Can't decline this post.", NULL, true); + if (!$post->canBePinnedBy($this->user->identity)) { + $this->flashFail("err", "Error", "Can't decline this post.", null, true); + } $post->setSuggested(2); $post->setDeleted(1); @@ -655,17 +723,17 @@ final class WallPresenter extends OpenVKPresenter $this->returnJson([ "success" => true, - "new_count" => (new Posts)->getSuggestedPostsCount($post->getWallOwner()->getId()) + "new_count" => (new Posts())->getSuggestedPostsCount($post->getWallOwner()->getId()), ]); } - function renderLikers(string $type, int $owner_id, int $item_id) + public function renderLikers(string $type, int $owner_id, int $item_id) { $this->assertUserLoggedIn(); - $item = NULL; + $item = null; $display_name = $type; - switch($type) { + switch ($type) { default: $this->notFound(); break; @@ -674,20 +742,21 @@ final class WallPresenter extends OpenVKPresenter $display_name = 'post'; break; case 'comment': - $item = (new \openvk\Web\Models\Repositories\Comments)->get($item_id); + $item = (new \openvk\Web\Models\Repositories\Comments())->get($item_id); break; case 'photo': - $item = (new \openvk\Web\Models\Repositories\Photos)->getByOwnerAndVID($owner_id, $item_id); + $item = (new \openvk\Web\Models\Repositories\Photos())->getByOwnerAndVID($owner_id, $item_id); break; case 'video': - $item = (new \openvk\Web\Models\Repositories\Videos)->getByOwnerAndVID($owner_id, $item_id); + $item = (new \openvk\Web\Models\Repositories\Videos())->getByOwnerAndVID($owner_id, $item_id); break; } - - if(!$item || $item->isDeleted() || !$item->canBeViewedBy($this->user->identity)) - $this->notFound(); - $page = (int)($this->queryParam('p') ?? 1); + if (!$item || $item->isDeleted() || !$item->canBeViewedBy($this->user->identity)) { + $this->notFound(); + } + + $page = (int) ($this->queryParam('p') ?? 1); $count = $item->getLikesCount(); $likers = iterator_to_array($item->getLikers($page, OPENVK_DEFAULT_PER_PAGE)); diff --git a/Web/Themes/Exceptions/IncompatibleThemeException.php b/Web/Themes/Exceptions/IncompatibleThemeException.php index e9113551..cd34f3a1 100644 --- a/Web/Themes/Exceptions/IncompatibleThemeException.php +++ b/Web/Themes/Exceptions/IncompatibleThemeException.php @@ -1,5 +1,7 @@ -id = $id; $this->ver = $ver; @@ -28,97 +32,102 @@ class Themepack $this->home = OPENVK_ROOT . "/themepacks/$id"; $this->enabled = $enabled; } - - function getId(): string + + public function getId(): string { return $this->id; } - - function isEnabled(): bool + + public function isEnabled(): bool { return $this->enabled; } - - function getName(?string $lang = NULL): string + + public function getName(?string $lang = null): string { - if(!$this->meta->name) + if (!$this->meta->name) { return $this->getId() . " theme"; - else if(is_array($this->meta->name)) + } elseif (is_array($this->meta->name)) { return $this->meta->name[$lang ?? "_"] ?? $this->getId() . " theme"; - else + } else { return $this->meta->name; + } } - - function getBaseDir(): string + + public function getBaseDir(): string { return $this->home; } - - function getVersion(): string + + public function getVersion(): string { return $this->ver; } - - function getDescription(): string + + public function getDescription(): string { return $this->meta->description ?? "A theme with name \"" . $this->getName() . "\""; } - - function getAuthor(): string + + public function getAuthor(): string { return $this->meta->author ?? $this->getName() . " authors"; } - - function inheritDefault(): bool + + public function inheritDefault(): bool { return $this->inh; } - - function overridesTemplates(): bool - { - return $this->tpl; + + public function overridesTemplates(): bool + { + return $this->tpl; } - - function fetchResource(string $resource, bool $processCSS = false): ?string + + public function fetchResource(string $resource, bool $processCSS = false): ?string { $file = "$this->home/$resource"; - if(!file_exists($file)) - return NULL; - + if (!file_exists($file)) { + return null; + } + $result = file_get_contents($file); - if(in_array(@end(explode(".", $resource)), $this->cssExtensions) && $processCSS) { + if (in_array(@end(explode(".", $resource)), $this->cssExtensions) && $processCSS) { $compiler = new CSSCompiler([ "cacheDir" => OPENVK_ROOT . "/tmp" ]); $compiler->setOutputStyle(OutputStyle::COMPRESSED); - + $result = $compiler->compileString($result, $file)->getCSS(); } - + return $result; } - - function fetchStyleSheet(): ?string + + public function fetchStyleSheet(): ?string { return $this->fetchResource("stylesheet.scss", true) ?? $this->fetchResource("stylesheet.css", true); } - - function fetchStaticResource(string $name): ?string + + public function fetchStaticResource(string $name): ?string { return $this->fetchResource("res/$name"); } - - static function themepackFromDir(string $dirname): Themepack + + public static function themepackFromDir(string $dirname): Themepack { $manifestFile = "$dirname/theme.yml"; - if(!file_exists($manifestFile)) + if (!file_exists($manifestFile)) { throw new Exceptions\NotThemeDirectoryException("Could not locate manifest at $dirname"); - + } + $manifest = (object) chandler_parse_yaml($manifestFile); - if(!isset($manifest->id) || !isset($manifest->version) || !isset($manifest->openvk_version) || !isset($manifest->metadata)) + if (!isset($manifest->id) || !isset($manifest->version) || !isset($manifest->openvk_version) || !isset($manifest->metadata)) { throw new Exceptions\MalformedManifestException("Manifest is missing required information"); - - if($manifest->openvk_version > Themepacks::THEMPACK_ENGINE_VERSION) + } + + if ($manifest->openvk_version > Themepacks::THEMPACK_ENGINE_VERSION) { throw new Exceptions\IncompatibleThemeException("Theme is built for newer OVK (themeEngine" . $manifest->openvk_version . ")"); - + } + return new static($manifest->id, $manifest->version, (bool) ($manifest->inherit_master ?? true), (bool) ($manifest->override_templates ?? false), (bool) ($manifest->enabled ?? true), (object) $manifest->metadata); } } diff --git a/Web/Themes/Themepacks.php b/Web/Themes/Themepacks.php index c28585d6..1907553a 100644 --- a/Web/Themes/Themepacks.php +++ b/Web/Themes/Themepacks.php @@ -1,94 +1,104 @@ -getId(); - if(isset($this->loadedThemepacks[$tid])) + if (isset($this->loadedThemepacks[$tid])) { trigger_error("Duplicate theme $tid found at $themeDir, skipping...", E_USER_WARNING); - else + } else { $this->loadedThemepacks[$tid] = $theme; - } catch(\Exception $e) { + } + } catch (\Exception $e) { trigger_error("Could not load theme at $themeDir. Exception: $e", E_USER_WARNING); } } } - + private function installUnpacked(string $path): bool { try { $theme = Themepack::themepackFromDir($path); $tid = $theme->getId(); - if(isset($this->loadedThemepacks[$tid])) + if (isset($this->loadedThemepacks[$tid])) { return false; - + } + rename($path, OPENVK_ROOT . "/themepacks/$tid"); $this->loadedThemepacks[$tid] = $theme; return true; - } catch(\Exception $e) { + } catch (\Exception $e) { return false; } } - - function getThemeList(): \Traversable + + public function getThemeList(): \Traversable { - foreach($this->loadedThemepacks as $id => $theme) - if($theme->isEnabled()) + foreach ($this->loadedThemepacks as $id => $theme) { + if ($theme->isEnabled()) { yield $id => ($theme->getName(Session::i()->get("lang", "ru"))); + } + } } - - function getAllThemes(): array + + public function getAllThemes(): array { return $this->loadedThemepacks; } - + /* ArrayAccess */ - - function offsetExists($offset): bool + + public function offsetExists($offset): bool { return $offset === Themepacks::DEFAULT_THEME_ID ? false : isset($this->loadedThemepacks[$offset]); } - - function offsetGet($offset) : mixed + + public function offsetGet($offset): mixed { return $this->loadedThemepacks[$offset]; } - - function offsetSet($offset, $value): void + + public function offsetSet($offset, $value): void { throw new ISE("Theme substitution in runtime is prohbited"); } - - function offsetUnset($offset): void + + public function offsetUnset($offset): void { $this->uninstall($offset); } - + /* /ArrayAccess */ - - function install(string $archivePath): bool + + public function install(string $archivePath): bool { - if(!file_exists($archivePath)) + if (!file_exists($archivePath)) { return false; - + } + $tmpDir = mkdir(tempnam(OPENVK_ROOT . "/tmp/themepack_artifacts/", "themex_")); try { $archive = new \CabArchive($archivePath); $archive->extract($tmpDir); - + return $this->installUnpacked($tmpDir); } catch (\Exception $e) { return false; @@ -96,16 +106,15 @@ class Themepacks implements \ArrayAccess rmdir($tmpDir); } } - - function uninstall(string $id): bool + + public function uninstall(string $id): bool { - if(!isset($loadedThemepacks[$id])) + if (!isset($loadedThemepacks[$id])) { return false; - + } + rmdir(OPENVK_ROOT . "/themepacks/$id"); unset($loadedThemepacks[$id]); return true; } - - use TSimpleSingleton; } diff --git a/Web/Util/Bitmask.php b/Web/Util/Bitmask.php index 7651514a..c34fcdc6 100644 --- a/Web/Util/Bitmask.php +++ b/Web/Util/Bitmask.php @@ -1,4 +1,7 @@ -data = str_pad(decbin($data), 63, "0", STR_PAD_RIGHT); $this->length = $length; - if((sizeof($mapping) - 1) > (64 / $length)) + if ((sizeof($mapping) - 1) > (64 / $length)) { throw new \OutOfRangeException("Mapping contains more keys than a bitmask can fit in itself."); - else + } else { $this->mapping = $mapping; + } } - + private function getOffsetByKey(string $key): int { $offset = array_search($key, $this->mapping); - if($offset === false) + if ($offset === false) { throw new \OutOfBoundsException("Key '$key' is not present in bitmask."); - + } + return $offset; } - - function toInteger(): int + + public function toInteger(): int { return (int) bindec($this->data); } - - function __toString(): string + + public function __toString(): string { return (string) $this->toInteger(); } - - function getNumberByOffset(int $offset): float + + public function getNumberByOffset(int $offset): float { $offset *= $this->length; - if($offset > (64 / $this->length)) + if ($offset > (64 / $this->length)) { return (float) 'NaN'; - + } + return (float) bindec(substr($this->data, $offset, $this->length)); } - - function getBoolByOffset(int $offset): ?bool + + public function getBoolByOffset(int $offset): ?bool { - if($this->length !== 1) - return NULL; - + if ($this->length !== 1) { + return null; + } + $number = $this->getNumberByOffset($offset); - return is_nan($number) ? NULL : (bool) $number; + return is_nan($number) ? null : (bool) $number; } - - function setByOffset(int $offset, int $number): void + + public function setByOffset(int $offset, int $number): void { $offset *= $this->length; - if(($offset + $this->length) > 64) + if (($offset + $this->length) > 64) { throw new \OutOfRangeException("$offset is invalid offset. Bitmask length is 64 bits."); - + } + $this->data = substr_replace($this->data, str_pad(decbin($number), $this->length, "0", STR_PAD_LEFT), $offset, $this->length); } - - function set($key, int $data): Bitmask + + public function set($key, int $data): Bitmask { - if(gettype($key) === "string") + if (gettype($key) === "string") { $this->setByOffset($this->getOffsetByKey($key), $data); - else if(gettype($key) === "int") + } elseif (gettype($key) === "int") { $this->setByOffset($key, $data); - else + } else { throw new TypeError("Key must be either offset (int) or a string index"); - + } + return $this; } - - function get($key) + + public function get($key) { - if(gettype($key) === "string") + if (gettype($key) === "string") { $key = $this->getOffsetByKey($key); - else if(gettype($key) !== "int") + } elseif (gettype($key) !== "int") { throw new TypeError("Key must be either offset (int) or a string index"); - + } + return $this->length === 1 ? $this->getBoolByOffset($key) : $this->getNumberByOffset($key); } } diff --git a/Web/Util/DateTime.php b/Web/Util/DateTime.php index 991d8032..6a82fe88 100644 --- a/Web/Util/DateTime.php +++ b/Web/Util/DateTime.php @@ -1,22 +1,26 @@ -timestamp = $timestamp ?? time(); $this->localizator = Localizator::i(); } - + protected function zmdate(): string { $then = date_create("@" . $this->timestamp); @@ -24,36 +28,39 @@ class DateTime $diff = date_diff($now, $then); $sessionOffset = intval(Session::i()->get("_timezoneOffset")); - if($diff->invert === 0) + if ($diff->invert === 0) { return ovk_strftime_safe("%e %B %Y ", $this->timestamp) . tr("time_at_sp") . ovk_strftime_safe(" %R", $this->timestamp); - - if(($this->timestamp + $sessionOffset) >= (strtotime("midnight") + $sessionOffset)) { # Today - if($diff->h >= 1) + } + + if (($this->timestamp + $sessionOffset) >= (strtotime("midnight") + $sessionOffset)) { # Today + if ($diff->h >= 1) { return tr("time_today") . tr("time_at_sp") . ovk_strftime_safe(" %R", $this->timestamp); - else if($diff->i < 2) + } elseif ($diff->i < 2) { return tr("time_just_now"); - else + } else { return $diff->i === 5 ? tr("time_exactly_five_minutes_ago") : tr("time_minutes_ago", $diff->i); - } else if(($this->timestamp + $sessionOffset) >= (strtotime("-1day midnight") + $sessionOffset)) { # Yesterday + } + } elseif (($this->timestamp + $sessionOffset) >= (strtotime("-1day midnight") + $sessionOffset)) { # Yesterday return tr("time_yesterday") . tr("time_at_sp") . ovk_strftime_safe(" %R", $this->timestamp); - } else if(ovk_strftime_safe("%Y", $this->timestamp) === ovk_strftime_safe("%Y", time())) { # In this year + } elseif (ovk_strftime_safe("%Y", $this->timestamp) === ovk_strftime_safe("%Y", time())) { # In this year return ovk_strftime_safe("%e %h ", $this->timestamp) . tr("time_at_sp") . ovk_strftime_safe(" %R", $this->timestamp); } else { return ovk_strftime_safe("%e %B %Y ", $this->timestamp) . tr("time_at_sp") . ovk_strftime_safe(" %R", $this->timestamp); } } - - function format(string $format, bool $useDate = false): string + + public function format(string $format, bool $useDate = false): string { - if(!$useDate) + if (!$useDate) { return ovk_strftime_safe($format, $this->timestamp); - else + } else { return date($format, $this->timestamp); + } } - - function relative(int $type = 0): string + + public function relative(int $type = 0): string { - switch($type) { + switch ($type) { case static::RELATIVE_FORMAT_NORMAL: return mb_convert_case($this->zmdate(), MB_CASE_TITLE_SIMPLE); case static::RELATIVE_FORMAT_LOWER: @@ -62,25 +69,26 @@ class DateTime return ""; } } - - function html(bool $capitalize = false, bool $short = false): string + + public function html(bool $capitalize = false, bool $short = false): string { - if($short) + if ($short) { $dt = $this->relative(static::RELATIVE_FORMAT_SHORT); - else if($capitalize) + } elseif ($capitalize) { $dt = $this->relative(static::RELATIVE_FORMAT_NORMAL); - else + } else { $dt = $this->relative(static::RELATIVE_FORMAT_LOWER); - + } + return ""; } - - function timestamp(): int + + public function timestamp(): int { return $this->timestamp; } - - function __toString(): string + + public function __toString(): string { return $this->relative(static::RELATIVE_FORMAT_LOWER); } diff --git a/Web/Util/Localizator.php b/Web/Util/Localizator.php index d73bec13..19a781d3 100644 --- a/Web/Util/Localizator.php +++ b/Web/Util/Localizator.php @@ -1,72 +1,78 @@ -$%Xm", $string, $matches); - for($i = 0; $i < sizeof($matches[1]); $i++) { + for ($i = 0; $i < sizeof($matches[1]); $i++) { $directive = $matches[1][$i]; - if($directive === "include") { + if ($directive === "include") { $includes[] = dirname(__FILE__) . "/../../locales/" . $matches[2][$i] . ".strings"; } else { trigger_error("Unknown preprocessor directive \"$directive\" in locale file, skipping. This will throw an error in a future version of Localizator::_getIncludes.", E_USER_DEPRECATED); } } - + return $includes; } - + protected function parse($file): array { $hash = sha1($file); - if(isset($GLOBALS["localizationCache_$hash"])) return $GLOBALS["localizationCache_$hash"]; - + if (isset($GLOBALS["localizationCache_$hash"])) { + return $GLOBALS["localizationCache_$hash"]; + } + $string = file_get_contents($file); $string = preg_replace("%^\/\*.*\*\/\r?$%m", "", $string); #Remove comments $array = []; - - foreach(preg_split("%;[\\r\\n]++%", $string) as $statement) { + + foreach (preg_split("%;[\\r\\n]++%", $string) as $statement) { $s = explode(" = ", trim($statement)); - + try { $array[eval("return $s[0];")] = eval("return $s[1];"); - } catch(\ParseError $ex) { - throw new \ParseError($ex->getMessage(). " near " . $s[0]); + } catch (\ParseError $ex) { + throw new \ParseError($ex->getMessage() . " near " . $s[0]); } } - - foreach(self::_getIncludes($string) as $include) + + foreach (self::_getIncludes($string) as $include) { $array = array_merge(@self::parse($include), $array); - + } + $GLOBALS["localizationCache_$hash"] = $array; return $array; } - - function _($id, $lang = NULL): string + + public function _($id, $lang = null): string { $lang = is_null($lang) ? static::DEFAULT_LANG : $lang; $array = @self::parse(dirname(__FILE__) . "/../../locales/$lang.strings"); - + return $array[$id] ?? "@$id"; } - - function export($lang = NULL): ?array + + public function export($lang = null): ?array { $lang = is_null($lang) ? static::DEFAULT_LANG : $lang; $array = @self::parse(dirname(__FILE__) . "/../../locales/$lang.strings"); return $array; } - - use TSimpleSingleton; } diff --git a/Web/Util/Makima/Makima.php b/Web/Util/Makima/Makima.php index 3fc7b014..92bb277d 100644 --- a/Web/Util/Makima/Makima.php +++ b/Web/Util/Makima/Makima.php @@ -1,19 +1,24 @@ -photos = $photos; } @@ -22,12 +27,13 @@ class Makima { [$width, $height] = $photo->getDimensions(); $ratio = $width / $height; - if($ratio >= 1.2) + if ($ratio >= 1.2) { return Makima::ORIENT_WIDE; - else if($ratio >= 0.8) + } elseif ($ratio >= 0.8) { return Makima::ORIENT_REGULAR; - else + } else { return Makima::ORIENT_SLIM; + } } private function calculateMultiThumbsHeight(array $ratios, float $w, float $m): float @@ -40,53 +46,54 @@ class Makima return array_slice($arr, $from, sizeof($arr) - $from - (sizeof($arr) - $to)); } - function computeMasonryLayout(float $maxWidth, float $maxHeight): MasonryLayout + public function computeMasonryLayout(float $maxWidth, float $maxHeight): MasonryLayout { $orients = []; $ratios = []; $count = sizeof($this->photos); - $result = new MasonryLayout; + $result = new MasonryLayout(); - foreach($this->photos as $photo) { + foreach ($this->photos as $photo) { $orients[] = $this->getOrientation($photo, $ratio); $ratios[] = $ratio; } $avgRatio = array_sum($ratios) / sizeof($ratios); - if($maxWidth < 0) + if ($maxWidth < 0) { $maxWidth = $maxHeight = 510; + } $maxRatio = $maxWidth / $maxHeight; $marginWidth = $marginHeight = 2; - switch($count) { + switch ($count) { case 2: - if( + if ( $orients == [Makima::ORIENT_WIDE, Makima::ORIENT_WIDE] # two wide pics && $avgRatio > (1.4 * $maxRatio) && abs($ratios[0] - $ratios[1]) < 0.2 # that can be positioned on top of each other ) { - $computedHeight = ceil( min( $maxWidth / $ratios[0], min( $maxWidth / $ratios[1], ($maxHeight - $marginHeight) / 2 ) ) ); + $computedHeight = ceil(min($maxWidth / $ratios[0], min($maxWidth / $ratios[1], ($maxHeight - $marginHeight) / 2))); $result->colSizes = [1]; $result->rowSizes = [1, 1]; $result->width = ceil($maxWidth); $result->height = $computedHeight * 2; $result->tiles = [new ThumbTile(1, 1, $maxWidth, $computedHeight), new ThumbTile(1, 1, $maxWidth, $computedHeight)]; - } else if( + } elseif ( $orients == [Makima::ORIENT_WIDE, Makima::ORIENT_WIDE] || $orients == [Makima::ORIENT_REGULAR, Makima::ORIENT_REGULAR] # two normal pics of same ratio ) { $computedWidth = ($maxWidth - $marginWidth) / 2; - $height = min( $computedWidth / $ratios[0], min( $computedWidth / $ratios[1], $maxHeight ) ); + $height = min($computedWidth / $ratios[0], min($computedWidth / $ratios[1], $maxHeight)); $result->colSizes = [1, 1]; $result->rowSizes = [1]; $result->width = ceil($maxWidth); $result->height = ceil($height); $result->tiles = [new ThumbTile(1, 1, $computedWidth, $height), new ThumbTile(1, 1, $computedWidth, $height)]; - } else /* next to each other, different ratios */ { + } else { /* next to each other, different ratios */ $w0 = ( - ($maxWidth - $marginWidth) / $ratios[1] / ( (1 / $ratios[0]) + (1 / $ratios[1]) ) + ($maxWidth - $marginWidth) / $ratios[1] / ((1 / $ratios[0]) + (1 / $ratios[1])) ); $w1 = $maxWidth - $w0 - $marginWidth; $h = min($maxHeight, min($w0 / $ratios[0], $w1 / $ratios[1])); @@ -97,10 +104,10 @@ class Makima $result->height = ceil($h); $result->tiles = [new ThumbTile(1, 1, $w0, $h), new ThumbTile(1, 1, $w1, $h)]; } - break; + break; case 3: # Three wide photos, we will put two of them below and one on top - if($orients == [Makima::ORIENT_WIDE, Makima::ORIENT_WIDE, Makima::ORIENT_WIDE]) { + if ($orients == [Makima::ORIENT_WIDE, Makima::ORIENT_WIDE, Makima::ORIENT_WIDE]) { $hCover = min($maxWidth / $ratios[0], ($maxHeight - $marginHeight) * (2 / 3)); $w2 = ($maxWidth - $marginWidth) / 2; $h = min($maxHeight - $hCover - $marginHeight, min($w2 / $ratios[1], $w2 / $ratios[2])); @@ -113,7 +120,7 @@ class Makima new ThumbTile(2, 1, $maxWidth, $hCover), new ThumbTile(1, 1, $w2, $h), new ThumbTile(1, 1, $w2, $h), ]; - } else /* Photos have different sizes or are not wide, so we will put one to left and two to the right */ { + } else { /* Photos have different sizes or are not wide, so we will put one to left and two to the right */ $wCover = min($maxHeight * $ratios[0], ($maxWidth - $marginWidth) * (3 / 4)); $h1 = ($ratios[1] * ($maxHeight - $marginHeight) / ($ratios[2] + $ratios[1])); $h0 = $maxHeight - $marginHeight - $h1; @@ -125,13 +132,13 @@ class Makima $result->height = ceil($maxHeight); $result->tiles = [ new ThumbTile(1, 2, $wCover, $maxHeight), new ThumbTile(1, 1, $w, $h0), - new ThumbTile(1, 1, $w, $h1), + new ThumbTile(1, 1, $w, $h1), ]; } - break; + break; case 4: # Four wide photos, we will put one to the top and rest below - if($orients == [Makima::ORIENT_WIDE, Makima::ORIENT_WIDE, Makima::ORIENT_WIDE, Makima::ORIENT_WIDE]) { + if ($orients == [Makima::ORIENT_WIDE, Makima::ORIENT_WIDE, Makima::ORIENT_WIDE, Makima::ORIENT_WIDE]) { $hCover = min($maxWidth / $ratios[0], ($maxHeight - $marginHeight) / (2 / 3)); $h = ($maxWidth - 2 * $marginWidth) / (array_sum($ratios) - $ratios[0]); $w0 = $h * $ratios[1]; @@ -144,10 +151,10 @@ class Makima $result->width = ceil($maxWidth); $result->height = ceil($hCover + $marginHeight + $h); $result->tiles = [ - new ThumbTile(3, 1, $maxWidth, $hCover), + new ThumbTile(3, 1, $maxWidth, $hCover), new ThumbTile(1, 1, $w0, $h), new ThumbTile(1, 1, $w1, $h), new ThumbTile(1, 1, $w2, $h), ]; - } else /* Four photos, we will put one to the left and rest to the right */ { + } else { /* Four photos, we will put one to the left and rest to the right */ $wCover = min($maxHeight * $ratios[0], ($maxWidth - $marginWidth) * (2 / 3)); $w = ($maxHeight - 2 * $marginHeight) / (1 / $ratios[1] + 1 / $ratios[2] + 1 / $ratios[3]); $h0 = $w / $ratios[1]; @@ -161,20 +168,22 @@ class Makima $result->height = ceil($maxHeight); $result->tiles = [ new ThumbTile(1, 3, $wCover, $maxHeight), new ThumbTile(1, 1, $w, $h0), - new ThumbTile(1, 1, $w, $h1), - new ThumbTile(1, 1, $w, $h2), + new ThumbTile(1, 1, $w, $h1), + new ThumbTile(1, 1, $w, $h2), ]; } - break; + break; default: // как лопать пузырики $ratiosCropped = []; - if($avgRatio > 1.1) { - foreach($ratios as $ratio) + if ($avgRatio > 1.1) { + foreach ($ratios as $ratio) { $ratiosCropped[] = max($ratio, 1.0); + } } else { - foreach($ratios as $ratio) + foreach ($ratios as $ratio) { $ratiosCropped[] = min($ratio, 1.0); + } } $tries = []; @@ -187,7 +196,7 @@ class Makima $tries[$firstLine = $count] = [$this->calculateMultiThumbsHeight($ratiosCropped, $maxWidth, $marginWidth)]; # Try two lines: - for($firstLine = 1; $firstLine < ($count - 1); $firstLine++) { + for ($firstLine = 1; $firstLine < ($count - 1); $firstLine++) { $secondLine = $count - $firstLine; $key = "$firstLine&$secondLine"; $tries[$key] = [ @@ -197,8 +206,8 @@ class Makima } # Try three lines: - for($firstLine = 1; $firstLine < ($count - 2); $firstLine++) { - for($secondLine = 1; $secondLine < ($count - $firstLine - 1); $secondLine++) { + for ($firstLine = 1; $firstLine < ($count - 2); $firstLine++) { + for ($secondLine = 1; $secondLine < ($count - $firstLine - 1); $secondLine++) { $thirdLine = $count - $firstLine - $secondLine; $key = "$firstLine&$secondLine&$thirdLine"; $tries[$key] = [ @@ -210,19 +219,22 @@ class Makima } # Now let's find the most optimal configuration: - $optimalConfiguration = $optimalDifference = NULL; - foreach($tries as $config => $heights) { + $optimalConfiguration = $optimalDifference = null; + foreach ($tries as $config => $heights) { $config = explode('&', (string) $config); # да да стринговые ключи пхп даже со стриктайпами автокастует к инту (см. 187) $confH = $marginHeight * (sizeof($heights) - 1); - foreach($heights as $h) + foreach ($heights as $h) { $confH += $h; + } $confDiff = abs($confH - $maxHeight); - if(sizeof($config) > 1) - if($config[0] > $config[1] || sizeof($config) >= 2 && $config[1] > $config[2]) + if (sizeof($config) > 1) { + if ($config[0] > $config[1] || sizeof($config) >= 2 && $config[1] > $config[2]) { $confDiff *= 1.1; + } + } - if(!$optimalConfiguration || $confDigff < $optimalDifference) { + if (!$optimalConfiguration || $confDigff < $optimalDifference) { $optimalConfiguration = $config; $optimalDifference = $confDiff; } @@ -241,11 +253,12 @@ class Makima $gridLineOffsets = []; $rowTiles = []; // vector> - for($i = 0; $i < sizeof($optimalConfiguration); $i++) { + for ($i = 0; $i < sizeof($optimalConfiguration); $i++) { $lineChunksNum = $optimalConfiguration[$i]; $lineThumbs = []; - for($j = 0; $j < $lineChunksNum; $j++) + for ($j = 0; $j < $lineChunksNum; $j++) { $lineThumbs[] = array_shift($thumbsRemain); + } $lineHeight = $optHeights[$i]; $totalHeight += $lineHeight; @@ -254,16 +267,18 @@ class Makima $totalWidth = 0; $row = []; - for($j = 0; $j < sizeof($lineThumbs); $j++) { + for ($j = 0; $j < sizeof($lineThumbs); $j++) { $thumbRatio = array_shift($ratiosRemain); - if($j == sizeof($lineThumbs) - 1) + if ($j == sizeof($lineThumbs) - 1) { $w = $maxWidth - $totalWidth; - else + } else { $w = $thumbRatio * $lineHeight; + } $totalWidth += ceil($w); - if($j < (sizeof($lineThumbs) - 1) && !in_array($totalWidth, $gridLineOffsets)) + if ($j < (sizeof($lineThumbs) - 1) && !in_array($totalWidth, $gridLineOffsets)) { $gridLineOffsets[] = $totalWidth; + } $tile = new ThumbTile(1, 1, $w, $lineHeight); $result->tiles[$k++] = $row[] = $tile; @@ -276,20 +291,22 @@ class Makima $gridLineOffsets[] = $maxWidth; $result->colSizes = [$gridLineOffsets[0]]; - for($i = sizeof($gridLineOffsets) - 1; $i > 0; $i--) + for ($i = sizeof($gridLineOffsets) - 1; $i > 0; $i--) { $result->colSizes[$i] = $gridLineOffsets[$i] - $gridLineOffsets[$i - 1]; + } - foreach($rowTiles as $row) { + foreach ($rowTiles as $row) { $columnOffset = 0; - foreach($row as $tile) { + foreach ($row as $tile) { $startColumn = $columnOffset; $width = 0; $tile->colSpan = 0; - for($i = $startColumn; $i < sizeof($result->colSizes); $i++) { + for ($i = $startColumn; $i < sizeof($result->colSizes); $i++) { $width += $result->colSizes[$i]; $tile->colSpan++; - if($width == $tile->width) + if ($width == $tile->width) { break; + } } $columnOffset += $tile->colSpan; @@ -297,7 +314,7 @@ class Makima } $result->height = ceil($totalHeight + $marginHeight * (sizeof($optHeights) - 1)); - break; + break; } return $result; diff --git a/Web/Util/Makima/MasonryLayout.php b/Web/Util/Makima/MasonryLayout.php index b23aa483..4ac18f29 100644 --- a/Web/Util/Makima/MasonryLayout.php +++ b/Web/Util/Makima/MasonryLayout.php @@ -1,7 +1,11 @@ -width, $this->height, $this->rowSpan, $this->colSpan] = [ceil($w), ceil($h), $rs, $cs]; } diff --git a/Web/Util/Shell/Exceptions/ShellUnavailableException.php b/Web/Util/Shell/Exceptions/ShellUnavailableException.php index 4869ab37..e49633f9 100644 --- a/Web/Util/Shell/Exceptions/ShellUnavailableException.php +++ b/Web/Util/Shell/Exceptions/ShellUnavailableException.php @@ -1,9 +1,12 @@ -command = $cmd; } - - function execute(?int &$result = nullptr): string + + public function execute(?int &$result = nullptr): string { $stdout = []; - if(Shell::isPowershell()) { + if (Shell::isPowershell()) { $cmd = escapeshellarg($this->command); exec("powershell -Command $this->command", $stdout, $result); } else { exec($this->command, $stdout, $result); } - + return implode(PHP_EOL, $stdout); } - - function start(): string + + public function start(): string { - if(Shell::isPowershell()) { + if (Shell::isPowershell()) { $cmd = escapeshellarg($this->command); pclose(popen("start /b powershell -Command $this->command", "r")); } else { system("nohup " . $this->command . " > /dev/null 2>/dev/null &"); } - + return $this->command; } }; diff --git a/Web/Util/Sms.php b/Web/Util/Sms.php index 1a2f35ba..a6030653 100644 --- a/Web/Util/Sms.php +++ b/Web/Util/Sms.php @@ -1,14 +1,18 @@ -enable) + if (!$conf->enable) { return false; - + } + $args = http_build_query([ "login" => $conf->client, "psw" => $conf->secret, @@ -18,17 +22,18 @@ class Sms "translit" => 2, "fmt" => 2, ]); - + $response = file_get_contents("https://smsc.ru/sys/send.php?$args"); - if(!$response) + if (!$response) { return false; - + } + $response = new \SimpleXMLElement($response); - if(isset($response->error_code)) { + if (isset($response->error_code)) { trigger_error("Could not send SMS to $to: $response->error (Exception $response->error_code)", E_USER_WARNING); return false; } - + return true; } } diff --git a/Web/Util/Telegram.php b/Web/Util/Telegram.php index 4c76ce2b..c6cb5cd4 100644 --- a/Web/Util/Telegram.php +++ b/Web/Util/Telegram.php @@ -1,18 +1,23 @@ -enable) + if (!$conf->enable) { return false; + } try { - (new GuzzleClient)->request( + (new GuzzleClient())->request( "POST", "https://api.telegram.org/bot{$conf->token}/sendMessage", [ @@ -21,7 +26,7 @@ class Telegram "text" => $text, "disable_web_page_preview" => $webPagePreview ? "true" : "false", "parse_mode" => "HTML", - ] + ], ] ); } catch (GuzzleClientException $ex) { diff --git a/Web/Util/Validator.php b/Web/Util/Validator.php index 51085a3d..a8b62419 100644 --- a/Web/Util/Validator.php +++ b/Web/Util/Validator.php @@ -1,30 +1,40 @@ - 64) return false; + if (is_null($domain)) { + return false; + } + if (iconv_strlen($user) > 64) { + return false; + } $domain = idn_to_ascii($domain) . "."; return checkdnsrr($domain, "MX"); } - function telegramValid(string $telegram): bool + public function telegramValid(string $telegram): bool { return (bool) preg_match("/^(?:t.me\/|@)?([a-zA-Z0-9_]{0,32})$/", $telegram); } - function passwordStrong(string $password): bool{ + public function passwordStrong(string $password): bool + { return (bool) preg_match("/^(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{8,}$/", $password); } - - use TSimpleSingleton; } diff --git a/bootstrap.php b/bootstrap.php index 75b3140e..42241ca4 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -1,22 +1,28 @@ -=")) + } + + if (!version_compare(PHP_VERSION, "7.3.0", ">=")) { $problems[] = "Incompatible PHP version: " . PHP_VERSION . " (7.3+ required, 7.4+ recommended)"; - - if(!is_dir(__DIR__ . "/vendor")) + } + + if (!is_dir(__DIR__ . "/vendor")) { $problems[] = "Composer dependencies missing"; - + } + $requiredExtensions = [ "gd", "imagick", @@ -40,11 +46,13 @@ function _ovk_check_environment(): void "session", "SPL", ]; - if(sizeof($missingExtensions = array_diff($requiredExtensions, get_loaded_extensions())) > 0) - foreach($missingExtensions as $extension) + if (sizeof($missingExtensions = array_diff($requiredExtensions, get_loaded_extensions())) > 0) { + foreach ($missingExtensions as $extension) { $problems[] = "Missing extension $extension"; - - if(sizeof($problems) > 0) { + } + } + + if (sizeof($problems) > 0) { require __DIR__ . "/misc/install_err.phtml"; exit; } @@ -52,17 +60,18 @@ function _ovk_check_environment(): void function ovkGetQuirk(string $quirk): int { - static $quirks = NULL; - if(!$quirks) + static $quirks = null; + if (!$quirks) { $quirks = chandler_parse_yaml(__DIR__ . "/quirks.yml"); - + } + return !is_null($v = $quirks[$quirk]) ? (int) $v : 0; } function ovk_proc_strtr(string $string, int $length = 0): string { $newString = iconv_substr($string, 0, $length); - + return $newString . ($string !== $newString ? "…" : ""); #if cut hasn't happened, don't append "..." } @@ -75,13 +84,14 @@ function knuth_shuffle(iterable $arr, int $seed): array srand($seed, MT_RAND_PHP); - for($i = 0; $i < $count; ++$i) + for ($i = 0; $i < $count; ++$i) { $ind[$i] = 0; + } - for($i = 0; $i < $count; ++$i) { + for ($i = 0; $i < $count; ++$i) { do { $index = rand() % $count; - } while($ind[$index] != 0); + } while ($ind[$index] != 0); $ind[$index] = 1; $retVal[$i] = $data[$index]; @@ -102,48 +112,52 @@ function tr(string $stringId, ...$variables): string { $localizer = Localizator::i(); $lang = Session::i()->get("lang", "ru"); - if($stringId === "__lang") + if ($stringId === "__lang") { return $lang; - + } + $output = $localizer->_($stringId, $lang); - if(sizeof($variables) > 0) { - if(gettype($variables[0]) === "integer") { - $numberedStringId = NULL; + if (sizeof($variables) > 0) { + if (gettype($variables[0]) === "integer") { + $numberedStringId = null; $cardinal = $variables[0]; - switch($cardinal) { + switch ($cardinal) { case 0: $numberedStringId = $stringId . "_zero"; - break; + break; case 1: $numberedStringId = $stringId . "_one"; - break; + break; default: $numberedStringId = $stringId . ($cardinal < 5 ? "_few" : "_other"); } - + $newOutput = $localizer->_($numberedStringId, $lang); - if($newOutput === "@$numberedStringId") { + if ($newOutput === "@$numberedStringId") { $newOutput = $localizer->_($stringId . "_other", $lang); - if($newOutput === ("@" . $stringId . "_other")) + if ($newOutput === ("@" . $stringId . "_other")) { $newOutput = $output; + } } $output = $newOutput; } - - for($i = 0; $i < sizeof($variables); $i++) + + for ($i = 0; $i < sizeof($variables); $i++) { $output = preg_replace("%(?set("lang", $lg); - else + } else { trigger_error("The language '$lg' is not available", E_USER_NOTICE); + } } function getLanguage(): string @@ -159,24 +173,30 @@ function getLanguages(): array function isLanguageAvailable($lg): bool { $lg_temp = false; - foreach(getLanguages() as $lang) { - if ($lang['code'] == $lg) $lg_temp = true; + foreach (getLanguages() as $lang) { + if ($lang['code'] == $lg) { + $lg_temp = true; + } } return $lg_temp; } function getBrowsersLanguage(): array { - if ($_SERVER['HTTP_ACCEPT_LANGUAGE'] != NULL) return mb_split(",", mb_split(";", $_SERVER['HTTP_ACCEPT_LANGUAGE'])[0]); - else return array(); + if ($_SERVER['HTTP_ACCEPT_LANGUAGE'] != null) { + return mb_split(",", mb_split(";", $_SERVER['HTTP_ACCEPT_LANGUAGE'])[0]); + } else { + return []; + } } function eventdb(): ?DatabaseConnection { $conf = OPENVK_ROOT_CONF["openvk"]["credentials"]["eventDB"]; - if(!$conf["enable"]) - return NULL; - + if (!$conf["enable"]) { + return null; + } + $db = (object) $conf["database"]; return DatabaseConnection::connect([ "dsn" => $db->dsn, @@ -192,43 +212,46 @@ function eventdb(): ?DatabaseConnection function ovk_proc_strtrim(string $string, int $length = 0): string { trigger_error("ovk_proc_strtrim is deprecated, please use fully compatible ovk_proc_strtr.", E_USER_DEPRECATED); - + return ovk_proc_strtr($string, $length); } -function ovk_strftime_safe(string $format, ?int $timestamp = NULL): string +function ovk_strftime_safe(string $format, ?int $timestamp = null): string { $sessionOffset = intval(Session::i()->get("_timezoneOffset")); - $str = strftime($format, $timestamp + ($sessionOffset * MINUTE) * -1 ?? time() + ($sessionOffset * MINUTE) * -1, tr("__locale") !== '@__locale' ? tr("__locale") : NULL); - if(PHP_SHLIB_SUFFIX === "dll" && version_compare(PHP_VERSION, "8.1.0", "<")) { + $str = strftime($format, $timestamp + ($sessionOffset * MINUTE) * -1 ?? time() + ($sessionOffset * MINUTE) * -1, tr("__locale") !== '@__locale' ? tr("__locale") : null); + if (PHP_SHLIB_SUFFIX === "dll" && version_compare(PHP_VERSION, "8.1.0", "<")) { $enc = tr("__WinEncoding"); - if($enc === "@__WinEncoding") + if ($enc === "@__WinEncoding") { $enc = "Windows-1251"; - + } + $nStr = iconv($enc, "UTF-8", $str); - if(!is_null($nStr)) + if (!is_null($nStr)) { $str = $nStr; + } } - + return $str; } function ovk_is_ssl(): bool { - if(!isset($GLOBALS["requestIsSSL"])) { + if (!isset($GLOBALS["requestIsSSL"])) { $GLOBALS["requestIsSSL"] = false; - - if(isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] !== "off") { + + if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] !== "off") { $GLOBALS["requestIsSSL"] = true; } else { $forwardedProto = $_SERVER["HTTP_X_FORWARDED_PROTO"] ?? ($_SERVER["HTTP_X_FORWARDED_PROTOCOL"] ?? ($_SERVER["HTTP_X_URL_SCHEME"] ?? "")); - if($forwardedProto === "https") + if ($forwardedProto === "https") { $GLOBALS["requestIsSSL"] = true; - else if(($_SERVER["HTTP_X_FORWARDED_SSL"] ?? "") === "on") + } elseif (($_SERVER["HTTP_X_FORWARDED_SSL"] ?? "") === "on") { $GLOBALS["requestIsSSL"] = true; + } } } - + return $GLOBALS["requestIsSSL"]; } @@ -265,53 +288,63 @@ function parseAttachments($attachments, array $allow_types = ['photo', 'video', 'repo' => 'openvk\Web\Models\Repositories\Documents', 'method' => 'getDocumentById', 'withKey' => true, - ] + ], ]; - foreach($exploded_attachments as $attachment_string) { - if(preg_match("/$imploded_types/", $attachment_string, $matches) == 1) { + foreach ($exploded_attachments as $attachment_string) { + if (preg_match("/$imploded_types/", $attachment_string, $matches) == 1) { try { $attachment_type = $matches[0]; - if(!$repositories[$attachment_type]) + if (!$repositories[$attachment_type]) { continue; - + } + $attachment_ids = str_replace($attachment_type, '', $attachment_string); - if($repositories[$attachment_type]['onlyId']) { + if ($repositories[$attachment_type]['onlyId']) { [$attachment_id] = array_map('intval', explode('_', $attachment_ids)); - + $repository_class = $repositories[$attachment_type]['repo']; - if(!$repository_class) continue; - $attachment_model = (new $repository_class)->{$repositories[$attachment_type]['method']}($attachment_id); + if (!$repository_class) { + continue; + } + $attachment_model = (new $repository_class())->{$repositories[$attachment_type]['method']}($attachment_id); $output_attachments[] = $attachment_model; - } elseif($repositories[$attachment_type]['withKey']) { + } elseif ($repositories[$attachment_type]['withKey']) { [$attachment_owner, $attachment_id, $access_key] = explode('_', $attachment_ids); - + $repository_class = $repositories[$attachment_type]['repo']; - if(!$repository_class) continue; - $attachment_model = (new $repository_class)->{$repositories[$attachment_type]['method']}((int)$attachment_owner, (int)$attachment_id, $access_key); - + if (!$repository_class) { + continue; + } + $attachment_model = (new $repository_class())->{$repositories[$attachment_type]['method']}((int) $attachment_owner, (int) $attachment_id, $access_key); + $output_attachments[] = $attachment_model; } else { [$attachment_owner, $attachment_id] = array_map('intval', explode('_', $attachment_ids)); - + $repository_class = $repositories[$attachment_type]['repo']; - if(!$repository_class) continue; - $attachment_model = (new $repository_class)->{$repositories[$attachment_type]['method']}($attachment_owner, $attachment_id); + if (!$repository_class) { + continue; + } + $attachment_model = (new $repository_class())->{$repositories[$attachment_type]['method']}($attachment_owner, $attachment_id); $output_attachments[] = $attachment_model; } - } catch(\Throwable) {continue;} + } catch (\Throwable) { + continue; + } } } return $output_attachments; } -function get_entity_by_id(int $id) +function get_entity_by_id(int $id) { - if($id > 0) - return (new openvk\Web\Models\Repositories\Users)->get($id); - - return (new openvk\Web\Models\Repositories\Clubs)->get(abs($id)); + if ($id > 0) { + return (new openvk\Web\Models\Repositories\Users())->get($id); + } + + return (new openvk\Web\Models\Repositories\Clubs())->get(abs($id)); } function get_entities(array $ids = []): array @@ -319,62 +352,70 @@ function get_entities(array $ids = []): array $main_result = []; $users = []; $clubs = []; - foreach($ids as $id) { - $id = (int)$id; - if($id < 0) + foreach ($ids as $id) { + $id = (int) $id; + if ($id < 0) { $clubs[] = abs($id); - - if($id > 0) + } + + if ($id > 0) { $users[] = $id; + } } - if(sizeof($users) > 0) { - $users_tmp = (new openvk\Web\Models\Repositories\Users)->getByIds($users); - foreach($users_tmp as $user) { + if (sizeof($users) > 0) { + $users_tmp = (new openvk\Web\Models\Repositories\Users())->getByIds($users); + foreach ($users_tmp as $user) { $main_result[] = $user; } } - - if(sizeof($clubs) > 0) { - $clubs_tmp = (new openvk\Web\Models\Repositories\Clubs)->getByIds($clubs); - foreach($clubs_tmp as $club) { + + if (sizeof($clubs) > 0) { + $clubs_tmp = (new openvk\Web\Models\Repositories\Clubs())->getByIds($clubs); + foreach ($clubs_tmp as $club) { $main_result[] = $club; } } - + return $main_result; } function ovk_scheme(bool $with_slashes = false): string { $scheme = ovk_is_ssl() ? "https" : "http"; - if($with_slashes) + if ($with_slashes) { $scheme .= "://"; - + } + return $scheme; } function check_copyright_link(string $link = ''): bool { - if(!str_contains($link, "https://") && !str_contains($link, "http://")) + if (!str_contains($link, "https://") && !str_contains($link, "http://")) { $link = "https://" . $link; - + } + # Existability - if(is_null($link) || empty($link)) + if (is_null($link) || empty($link)) { throw new \InvalidArgumentException("Empty link"); + } # Length - if(iconv_strlen($link) < 2 || iconv_strlen($link) > 400) + if (iconv_strlen($link) < 2 || iconv_strlen($link) > 400) { throw new \LengthException("Link is too long"); + } # Match URL regex # stolen from http://urlregex.com/ - if (!preg_match("%^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@|\d{1,3}(?:\.\d{1,3}){3}|(?:(?:[a-z\d\x{00a1}-\x{ffff}]+-?)*[a-z\d\x{00a1}-\x{ffff}]+|xn--[a-z\d-]+)(?:\.(?:[a-z\d\x{00a1}-\x{ffff}]+-?)*[a-z\d\x{00a1}-\x{ffff}]+)*(?:\.(?:xn--[a-z\d-]+|[a-z\x{00a1}-\x{ffff}]{2,6})))(?::\d+)?(?:[^\s]*)?$%iu", $link)) + if (!preg_match("%^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@|\d{1,3}(?:\.\d{1,3}){3}|(?:(?:[a-z\d\x{00a1}-\x{ffff}]+-?)*[a-z\d\x{00a1}-\x{ffff}]+|xn--[a-z\d-]+)(?:\.(?:[a-z\d\x{00a1}-\x{ffff}]+-?)*[a-z\d\x{00a1}-\x{ffff}]+)*(?:\.(?:xn--[a-z\d-]+|[a-z\x{00a1}-\x{ffff}]{2,6})))(?::\d+)?(?:[^\s]*)?$%iu", $link)) { throw new \InvalidArgumentException("Invalid link format"); + } - $banEntries = (new openvk\Web\Models\Repositories\BannedLinks)->check($link); - if(sizeof($banEntries) > 0) + $banEntries = (new openvk\Web\Models\Repositories\BannedLinks())->check($link); + if (sizeof($banEntries) > 0) { throw new \LogicException("Suspicious link"); + } return true; } @@ -401,28 +442,32 @@ function downloadable_name(string $text): string return preg_replace('/[\\/:*?"<>|]/', '_', str_replace(' ', '_', $text)); } -return (function() { +return (function () { _ovk_check_environment(); require __DIR__ . "/vendor/autoload.php"; setlocale(LC_TIME, "POSIX"); # TODO: Default language in config - if(Session::i()->get("lang") == NULL) { + if (Session::i()->get("lang") == null) { $languages = array_reverse(getBrowsersLanguage()); - foreach($languages as $lg) { - if(isLanguageAvailable($lg)) setLanguage($lg); + foreach ($languages as $lg) { + if (isLanguageAvailable($lg)) { + setLanguage($lg); + } } } - - if(empty($_SERVER["REQUEST_SCHEME"])) + + if (empty($_SERVER["REQUEST_SCHEME"])) { $_SERVER["REQUEST_SCHEME"] = empty($_SERVER["HTTPS"]) ? "HTTP" : "HTTPS"; + } $showCommitHash = true; # plz remove when release - if(is_dir($gitDir = OPENVK_ROOT . "/.git") && $showCommitHash) + if (is_dir($gitDir = OPENVK_ROOT . "/.git") && $showCommitHash) { $ver = trim(`git --git-dir="$gitDir" log --pretty="%h" -n1 HEAD` ?? "Unknown version") . "-nightly"; - else + } else { $ver = "Public Technical Preview 4"; + } # Unix time constants define('MINUTE', 60); @@ -432,7 +477,7 @@ return (function() { define('MONTH', 30 * DAY); define('YEAR', 365 * DAY); - define("nullptr", NULL); + define("nullptr", null); define("OPENVK_DEFAULT_INSTANCE_NAME", "OpenVK", false); define("OPENVK_VERSION", "Altair Preview ($ver)", false); define("OPENVK_DEFAULT_PER_PAGE", 10, false); diff --git a/composer.json b/composer.json index 57810cd1..1020a4f7 100644 --- a/composer.json +++ b/composer.json @@ -1,4 +1,8 @@ { + "scripts": { + "fix": "php-cs-fixer fix", + "lint": "php-cs-fixer fix --dry-run --diff --verbose" + }, "require": { "php": "~7.3||~8.1", "guzzlehttp/guzzle": "^6.5", @@ -22,5 +26,8 @@ "php81_bc/strftime": "^0.0.2", "ext-iconv": "*" }, - "minimum-stability": "beta" + "minimum-stability": "beta", + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.68" + } } diff --git a/composer.lock b/composer.lock index ffbb1814..3e7e2d72 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "987e26c5520b71fccd0cd31de00eead2", + "content-hash": "b92d2ddd207f394a31c429c65d1785a7", "packages": [ { "name": "al/emoji-detector", @@ -2590,7 +2590,1688 @@ "time": "2024-04-17T12:47:41+00:00" } ], - "packages-dev": [], + "packages-dev": [ + { + "name": "clue/ndjson-react", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/clue/reactphp-ndjson.git", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", + "shasum": "" + }, + "require": { + "php": ">=5.3", + "react/stream": "^1.2" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", + "react/event-loop": "^1.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Clue\\React\\NDJson\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", + "homepage": "https://github.com/clue/reactphp-ndjson", + "keywords": [ + "NDJSON", + "json", + "jsonlines", + "newline", + "reactphp", + "streaming" + ], + "support": { + "issues": "https://github.com/clue/reactphp-ndjson/issues", + "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-12-23T10:58:28+00:00" + }, + { + "name": "composer/pcre", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.3", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.3" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-09-19T14:15:21+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-05-06T16:37:16+00:00" + }, + { + "name": "evenement/evenement", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/igorw/evenement.git", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9 || ^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Evenement\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "description": "Événement is a very simple event dispatching library for PHP", + "keywords": [ + "event-dispatcher", + "event-emitter" + ], + "support": { + "issues": "https://github.com/igorw/evenement/issues", + "source": "https://github.com/igorw/evenement/tree/v3.0.2" + }, + "time": "2023-08-08T05:53:35+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "8520451a140d3f46ac33042715115e290cf5785f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", + "reference": "8520451a140d3f46ac33042715115e290cf5785f", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.2", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.2.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2024-08-06T10:04:20+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.68.5", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "7bedb718b633355272428c60736dc97fb96daf27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/7bedb718b633355272428c60736dc97fb96daf27", + "reference": "7bedb718b633355272428c60736dc97fb96daf27", + "shasum": "" + }, + "require": { + "clue/ndjson-react": "^1.0", + "composer/semver": "^3.4", + "composer/xdebug-handler": "^3.0.3", + "ext-filter": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "fidry/cpu-core-counter": "^1.2", + "php": "^7.4 || ^8.0", + "react/child-process": "^0.6.5", + "react/event-loop": "^1.0", + "react/promise": "^2.0 || ^3.0", + "react/socket": "^1.0", + "react/stream": "^1.0", + "sebastian/diff": "^4.0 || ^5.1 || ^6.0", + "symfony/console": "^5.4 || ^6.4 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.4 || ^7.0", + "symfony/finder": "^5.4 || ^6.4 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.4 || ^7.0", + "symfony/polyfill-mbstring": "^1.31", + "symfony/polyfill-php80": "^1.31", + "symfony/polyfill-php81": "^1.31", + "symfony/process": "^5.4 || ^6.4 || ^7.2", + "symfony/stopwatch": "^5.4 || ^6.4 || ^7.0" + }, + "require-dev": { + "facile-it/paraunit": "^1.3.1 || ^2.4", + "infection/infection": "^0.29.8", + "justinrainbow/json-schema": "^5.3 || ^6.0", + "keradus/cli-executor": "^2.1", + "mikey179/vfsstream": "^1.6.12", + "php-coveralls/php-coveralls": "^2.7", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.5", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.5", + "phpunit/phpunit": "^9.6.22 || ^10.5.40 || ^11.5.2", + "symfony/var-dumper": "^5.4.48 || ^6.4.15 || ^7.2.0", + "symfony/yaml": "^5.4.45 || ^6.4.13 || ^7.2.0" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "exclude-from-classmap": [ + "src/Fixer/Internal/*" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.68.5" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2025-01-30T17:00:50+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/ef29f6d262798707a9edd554e2b82517ef3a9376", + "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/2.0.0" + }, + "time": "2021-07-14T16:41:46+00:00" + }, + { + "name": "react/cache", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/cache.git", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/promise": "^3.0 || ^2.0 || ^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, Promise-based cache interface for ReactPHP", + "keywords": [ + "cache", + "caching", + "promise", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/cache/issues", + "source": "https://github.com/reactphp/cache/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2022-11-30T15:59:55+00:00" + }, + { + "name": "react/child-process", + "version": "v0.6.6", + "source": { + "type": "git", + "url": "https://github.com/reactphp/child-process.git", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/1721e2b93d89b745664353b9cfc8f155ba8a6159", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/event-loop": "^1.2", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/socket": "^1.16", + "sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\ChildProcess\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven library for executing child processes with ReactPHP.", + "keywords": [ + "event-driven", + "process", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/child-process/issues", + "source": "https://github.com/reactphp/child-process/tree/v0.6.6" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-01-01T16:37:48+00:00" + }, + { + "name": "react/dns", + "version": "v1.13.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/dns.git", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/cache": "^1.0 || ^0.6 || ^0.5", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.7 || ^1.2.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3 || ^2", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Dns\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async DNS resolver for ReactPHP", + "keywords": [ + "async", + "dns", + "dns-resolver", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/dns/issues", + "source": "https://github.com/reactphp/dns/tree/v1.13.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-13T14:18:03+00:00" + }, + { + "name": "react/event-loop", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/event-loop.git", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "suggest": { + "ext-pcntl": "For signal handling support when using the StreamSelectLoop" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\EventLoop\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", + "keywords": [ + "asynchronous", + "event-loop" + ], + "support": { + "issues": "https://github.com/reactphp/event-loop/issues", + "source": "https://github.com/reactphp/event-loop/tree/v1.5.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2023-11-13T13:48:05+00:00" + }, + { + "name": "react/promise", + "version": "v3.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/8a164643313c71354582dc850b42b33fa12a4b63", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63", + "shasum": "" + }, + "require": { + "php": ">=7.1.0" + }, + "require-dev": { + "phpstan/phpstan": "1.10.39 || 1.4.10", + "phpunit/phpunit": "^9.6 || ^7.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "React\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "support": { + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v3.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-05-24T10:39:05+00:00" + }, + { + "name": "react/socket", + "version": "v1.16.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/socket.git", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/dns": "^1.13", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.6 || ^1.2.1", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3.3 || ^2", + "react/promise-stream": "^1.4", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Socket\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", + "keywords": [ + "Connection", + "Socket", + "async", + "reactphp", + "stream" + ], + "support": { + "issues": "https://github.com/reactphp/socket/issues", + "source": "https://github.com/reactphp/socket/tree/v1.16.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-07-26T10:38:09+00:00" + }, + { + "name": "react/stream", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/stream.git", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.8", + "react/event-loop": "^1.2" + }, + "require-dev": { + "clue/stream-filter": "~1.2", + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", + "keywords": [ + "event-driven", + "io", + "non-blocking", + "pipe", + "reactphp", + "readable", + "stream", + "writable" + ], + "support": { + "issues": "https://github.com/reactphp/stream/issues", + "source": "https://github.com/reactphp/stream/tree/v1.4.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-11T12:45:25+00:00" + }, + { + "name": "sebastian/diff", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:53:05+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "87a71856f2f56e4100373e92529eed3171695cfb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb", + "reference": "87a71856f2f56e4100373e92529eed3171695cfb", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v7.2.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-30T19:00:17+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/7da8fbac9dcfef75ffc212235d76b2754ce0cf50", + "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-20T11:17:29+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/process", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-06T14:24:19+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v7.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "e46690d5b9d7164a6d061cab1e8d46141b9f49df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/e46690d5b9d7164a6d061cab1e8d46141b9f49df", + "reference": "e46690d5b9d7164a6d061cab1e8d46141b9f49df", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v7.2.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-18T14:28:33+00:00" + } + ], "aliases": [], "minimum-stability": "beta", "stability-flags": {