1
0
Fork 0
mirror of https://codeberg.org/demostf/api.git synced 2026-06-03 18:04:08 +02:00

stricter cs

This commit is contained in:
Robin Appelman 2017-07-30 15:03:52 +02:00
commit d9a843ecd6
54 changed files with 346 additions and 168 deletions

View file

@ -7,7 +7,15 @@ $finder = PhpCsFixer\Finder::create()
return PhpCsFixer\Config::create() return PhpCsFixer\Config::create()
->setRules([ ->setRules([
'@PSR2' => true, '@PSR2' => true,
'@Symfony' => true,
'@Symfony:risky' => true,
'strict_param' => true,
'array_syntax' => ['syntax' => 'short'], 'array_syntax' => ['syntax' => 'short'],
'braces' => ['position_after_functions_and_oop_constructs' => 'same'], 'braces' => ['position_after_functions_and_oop_constructs' => 'same'],
'declare_strict_types' => true,
'concat_space' => ['spacing' => 'one'],
'ternary_to_null_coalescing' => true,
'phpdoc_order' => true,
'visibility_required' => true,
]) ])
->setFinder($finder); ->setFinder($finder);

View file

@ -23,4 +23,4 @@ tests: phpunit mocha
.PHONY: lint .PHONY: lint
lint: lint:
vendor/bin/php-cs-fixer fix vendor/bin/php-cs-fixer fix --allow-risky yes

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API; namespace Demostf\API;

View file

@ -1,9 +1,12 @@
<?php namespace Demostf\API\Controllers; <?php
declare(strict_types=1);
namespace Demostf\API\Controllers;
use Ehesp\SteamLogin\SteamLogin; use Ehesp\SteamLogin\SteamLogin;
use Demostf\API\Providers\AuthProvider; use Demostf\API\Providers\AuthProvider;
use Demostf\API\Providers\UserProvider; use Demostf\API\Providers\UserProvider;
use flight\Engine;
class AuthController extends BaseController { class AuthController extends BaseController {
/** /**
@ -38,7 +41,7 @@ class AuthController extends BaseController {
'token' => $token, 'token' => $token,
'steamid' => $userData['steamid'], 'steamid' => $userData['steamid'],
'name' => $userData['name'], 'name' => $userData['name'],
'key' => $userData['key'] 'key' => $userData['key'],
]); ]);
} }
@ -55,7 +58,7 @@ class AuthController extends BaseController {
'token' => $token, 'token' => $token,
'steamid' => null, 'steamid' => null,
'name' => null, 'name' => null,
'key' => null 'key' => null,
]); ]);
} }

View file

@ -1,18 +1,25 @@
<?php namespace Demostf\API\Controllers; <?php
declare(strict_types=1);
namespace Demostf\API\Controllers;
class BaseController { class BaseController {
protected function query($name, $default) { protected function query($name, $default) {
$request = \Flight::request(); $request = \Flight::request();
return isset($request->query[$name]) ? $request->query[$name] : $default; return isset($request->query[$name]) ? $request->query[$name] : $default;
} }
protected function file($name) { protected function file($name) {
$request = \Flight::request(); $request = \Flight::request();
return $request->files[$name]; return $request->files[$name];
} }
protected function post($name, $default = null) { protected function post($name, $default = null) {
$request = \Flight::request(); $request = \Flight::request();
return isset($request->data[$name]) ? $request->data[$name] : $default; return isset($request->data[$name]) ? $request->data[$name] : $default;
} }
} }

View file

@ -1,9 +1,12 @@
<?php namespace Demostf\API\Controllers; <?php
declare(strict_types=1);
namespace Demostf\API\Controllers;
use Demostf\API\Providers\ChatProvider; use Demostf\API\Providers\ChatProvider;
use Demostf\API\Providers\DemoListProvider; use Demostf\API\Providers\DemoListProvider;
use Demostf\API\Providers\DemoProvider; use Demostf\API\Providers\DemoProvider;
use flight\Engine;
class DemoController extends BaseController { class DemoController extends BaseController {
/** @var DemoProvider */ /** @var DemoProvider */
@ -16,7 +19,12 @@ class DemoController extends BaseController {
private $editKey; private $editKey;
public function __construct(DemoProvider $demoProvider, ChatProvider $chatProvider, DemoListProvider $demoListProvider, string $editKey) { public function __construct(
DemoProvider $demoProvider,
ChatProvider $chatProvider,
DemoListProvider $demoListProvider,
string $editKey
) {
$this->demoProvider = $demoProvider; $this->demoProvider = $demoProvider;
$this->chatProvider = $chatProvider; $this->chatProvider = $chatProvider;
$this->demoListProvider = $demoListProvider; $this->demoListProvider = $demoListProvider;
@ -27,7 +35,7 @@ class DemoController extends BaseController {
* @param string $id * @param string $id
*/ */
public function get($id) { public function get($id) {
\Flight::json($this->demoProvider->get($id)); \Flight::json($this->demoProvider->get(intval($id, 10)));
} }
protected function getFilter() { protected function getFilter() {
@ -56,6 +64,7 @@ class DemoController extends BaseController {
$filter['playerCount'] = [7, 8, 9]; $filter['playerCount'] = [7, 8, 9];
break; break;
} }
return $filter; return $filter;
} }
@ -65,16 +74,16 @@ class DemoController extends BaseController {
\Flight::json($this->demoListProvider->listDemos($page, $this->getFilter(), $order)); \Flight::json($this->demoListProvider->listDemos($page, $this->getFilter(), $order));
} }
public function listProfile($steamid) { public function listProfile($steamId) {
$page = $this->query('page', 1); $page = $this->query('page', 1);
$where = $this->getFilter(); $where = $this->getFilter();
$where['players'][] = $steamid; $where['players'][] = $steamId;
\Flight::json($this->demoListProvider->listProfile($page, $where)); \Flight::json($this->demoListProvider->listProfile($page, $where));
} }
public function listUploads($steamid) { public function listUploads($steamId) {
$page = $this->query('page', 1); $page = $this->query('page', 1);
\Flight::json($this->demoListProvider->listUploads($steamid, $page, $this->getFilter())); \Flight::json($this->demoListProvider->listUploads($steamId, $page, $this->getFilter()));
} }
public function chat($demoId) { public function chat($demoId) {
@ -82,11 +91,11 @@ class DemoController extends BaseController {
} }
public function setDemoUrl($id) { public function setDemoUrl($id) {
$hash = $this->post('hash', ''); $hash = (string) $this->post('hash', '');
$backend = $this->post('backend', ''); $backend = (string) $this->post('backend', '');
$path = $this->post('path', ''); $path = (string) $this->post('path', '');
$url = $this->post('url', ''); $url = (string) $this->post('url', '');
$editKey = $this->post('key', ''); $editKey = (string) $this->post('key', '');
if ($editKey !== $this->editKey || $editKey === '') { if ($editKey !== $this->editKey || $editKey === '') {
throw new \InvalidArgumentException('Invalid key'); throw new \InvalidArgumentException('Invalid key');
} }

View file

@ -1,7 +1,10 @@
<?php namespace Demostf\API\Controllers; <?php
declare(strict_types=1);
namespace Demostf\API\Controllers;
use Demostf\API\Providers\InfoProvider; use Demostf\API\Providers\InfoProvider;
use flight\Engine;
class InfoController extends BaseController { class InfoController extends BaseController {
/** @var InfoProvider */ /** @var InfoProvider */

View file

@ -1,7 +1,10 @@
<?php namespace Demostf\API\Controllers; <?php
declare(strict_types=1);
namespace Demostf\API\Controllers;
use Demostf\API\Providers\UploadProvider; use Demostf\API\Providers\UploadProvider;
use flight\Engine;
class UploadController extends BaseController { class UploadController extends BaseController {
private $uploadProvider; private $uploadProvider;
@ -11,13 +14,14 @@ class UploadController extends BaseController {
} }
public function upload() { public function upload() {
$key = $this->post('key', ''); $key = (string) $this->post('key', '');
$red = $this->post('red', 'RED'); $red = (string) $this->post('red', 'RED');
$blu = $this->post('blu', 'BLU'); $blu = (string) $this->post('blu', 'BLU');
$name = $this->post('name', 'Unnamed'); $name = (string) $this->post('name', 'Unnamed');
$demo = $this->file('demo'); $demo = $this->file('demo');
if (is_null($demo)) { if (null === $demo) {
echo 'No demo uploaded'; echo 'No demo uploaded';
return; return;
} }
$demoFile = $demo['tmp_name']; $demoFile = $demo['tmp_name'];

View file

@ -1,9 +1,10 @@
<?php namespace Demostf\API\Controllers; <?php
declare(strict_types=1);
namespace Demostf\API\Controllers;
use Ehesp\SteamLogin\SteamLogin;
use Demostf\API\Providers\AuthProvider;
use Demostf\API\Providers\UserProvider; use Demostf\API\Providers\UserProvider;
use flight\Engine;
class UserController extends BaseController { class UserController extends BaseController {
/** /**
@ -15,8 +16,8 @@ class UserController extends BaseController {
$this->userProvider = $userProvider; $this->userProvider = $userProvider;
} }
public function get($steamid) { public function get($steamId) {
\Flight::json($this->userProvider->get($steamid)); \Flight::json($this->userProvider->get($steamId));
} }
public function search() { public function search() {

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Data; namespace Demostf\API\Data;
@ -78,7 +80,7 @@ class DemoPlayer implements \JsonSerializable {
} }
public static function fromRow($row): DemoPlayer { public static function fromRow($row): DemoPlayer {
return new DemoPlayer( return new self(
$row['id'], $row['id'],
$row['user_id'], $row['user_id'],
$row['name'], $row['name'],
@ -103,7 +105,7 @@ class DemoPlayer implements \JsonSerializable {
'avatar' => $this->getAvatar(), 'avatar' => $this->getAvatar(),
'kills' => $this->getKills(), 'kills' => $this->getKills(),
'assists' => $this->getAssists(), 'assists' => $this->getAssists(),
'deaths' => $this->getDeaths() 'deaths' => $this->getDeaths(),
]; ];
} }
} }

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Data; namespace Demostf\API\Data;

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Data; namespace Demostf\API\Data;

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Data; namespace Demostf\API\Data;

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Data; namespace Demostf\API\Data;

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Data; namespace Demostf\API\Data;

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Data; namespace Demostf\API\Data;

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Data; namespace Demostf\API\Data;

View file

@ -1,4 +1,6 @@
<?php declare(strict_types = 1); <?php
declare(strict_types=1);
namespace Demostf\API\Data; namespace Demostf\API\Data;
@ -47,12 +49,12 @@ class User implements \JsonSerializable {
'id' => $this->getId(), 'id' => $this->getId(),
'steamid' => $this->getSteamId(), 'steamid' => $this->getSteamId(),
'name' => $this->getName(), 'name' => $this->getName(),
'avatar' => $this->getAvatar() 'avatar' => $this->getAvatar(),
]; ];
} }
public static function fromRow(array $row): User { public static function fromRow(array $row): User {
return new User( return new self(
(int) $row['id'], (int) $row['id'],
$row['steamid'], $row['steamid'],
$row['name'], $row['name'],

View file

@ -1,10 +1,14 @@
<?php namespace Demostf\API\Demo; <?php
declare(strict_types=1);
namespace Demostf\API\Demo;
class ChatMessage { class ChatMessage {
/** @var string */ /** @var string */
private $user; private $user;
/** @var integer */ /** @var int */
private $time; private $time;
/** @var string */ /** @var string */

View file

@ -1,4 +1,8 @@
<?php namespace Demostf\API\Demo; <?php
declare(strict_types=1);
namespace Demostf\API\Demo;
use Demostf\API\Data\DemoPlayer; use Demostf\API\Data\DemoPlayer;
use Demostf\API\Data\User; use Demostf\API\Data\User;
@ -146,7 +150,7 @@ class Demo implements \JsonSerializable {
} }
public static function fromRow($row): Demo { public static function fromRow($row): Demo {
return new Demo( return new self(
(int) $row['id'], (int) $row['id'],
$row['url'], $row['url'],
$row['name'], $row['name'],
@ -208,11 +212,12 @@ class Demo implements \JsonSerializable {
'uploader' => $this->uploaderUser ? $this->getUploaderUser()->jsonSerialize() : $this->getUploader(), 'uploader' => $this->uploaderUser ? $this->getUploaderUser()->jsonSerialize() : $this->getUploader(),
'hash' => $this->getHash(), 'hash' => $this->getHash(),
'backend' => $this->getBackend(), 'backend' => $this->getBackend(),
'path' => $this->getPath() 'path' => $this->getPath(),
]; ];
if ($this->players) { if ($this->players) {
$data['players'] = $this->getPlayers(); $data['players'] = $this->getPlayers();
} }
return $data; return $data;
} }
} }

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Demo; namespace Demostf\API\Demo;

View file

@ -1,4 +1,8 @@
<?php namespace Demostf\API\Demo; <?php
declare(strict_types=1);
namespace Demostf\API\Demo;
use Demostf\API\Data\StoredDemo; use Demostf\API\Data\StoredDemo;
@ -20,6 +24,7 @@ class DemoStore {
} }
rename($sourcePath, $target); rename($sourcePath, $target);
chmod($target, 0755); chmod($target, 0755);
return new StoredDemo($this->getUrl($name), 'static', $target); return new StoredDemo($this->getUrl($name), 'static', $target);
} }

View file

@ -1,9 +1,11 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Demo; namespace Demostf\API\Demo;
/** /**
* HL2 demo metadata * HL2 demo metadata.
*/ */
class Header { class Header {
/** /**
@ -132,7 +134,7 @@ class Header {
} }
public static function fromArray(array $info) { public static function fromArray(array $info) {
return new Header( return new self(
$info['type'], $info['type'],
$info['version'], $info['version'],
$info['protocol'], $info['protocol'],

View file

@ -1,12 +1,16 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Demo; namespace Demostf\API\Demo;
class HeaderParser { class HeaderParser {
/** /**
* @param string $head string containing the demo header binary data * @param string $head string containing the demo header binary data
* @return Header *
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*
* @return Header
*/ */
public function parseString(string $head): Header { public function parseString(string $head): Header {
$info = @unpack( $info = @unpack(
@ -16,33 +20,40 @@ class HeaderParser {
if (!isset($info['type']) || $info['type'] !== 'HL2DEMO') { if (!isset($info['type']) || $info['type'] !== 'HL2DEMO') {
throw new \InvalidArgumentException('Not an HL2 demo'); throw new \InvalidArgumentException('Not an HL2 demo');
} }
return Header::fromArray($info); return Header::fromArray($info);
} }
/** /**
* Parse demo info from a stream * Parse demo info from a stream.
* *
* @param resource $stream * @param resource $stream
* @return Header *
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*
* @return Header
*/ */
public function parseStream($stream): Header { public function parseStream($stream): Header {
$head = fread($stream, 2048); $head = fread($stream, 2048);
return $this->parseString($head); return $this->parseString($head);
} }
/** /**
* Parse demo info from a local file * Parse demo info from a local file.
* *
* @param string $path * @param string $path
* @return Header *
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*
* @return Header
*/ */
public function parseHeader(string $path): Header { public function parseHeader(string $path): Header {
if (!is_readable($path)) { if (!is_readable($path)) {
throw new \InvalidArgumentException('Unable to open demo: ' . $path); throw new \InvalidArgumentException('Unable to open demo: ' . $path);
} }
$fh = fopen($path, 'rb'); $fh = fopen($path, 'rb');
return $this->parseStream($fh); return $this->parseStream($fh);
} }
} }

View file

@ -1,14 +1,15 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Demo; namespace Demostf\API\Demo;
use Demostf\API\Data\ParsedDemo; use Demostf\API\Data\ParsedDemo;
use Demostf\API\Data\ParsedKill; use Demostf\API\Data\ParsedKill;
use Demostf\API\Data\ParsedPlayer; use Demostf\API\Data\ParsedPlayer;
use Demostf\API\Data\Player;
/** /**
* Higher level parser * Higher level parser.
* *
* Processes the raw demo.js output to something more suitable for our purpose * Processes the raw demo.js output to something more suitable for our purpose
*/ */
@ -22,7 +23,7 @@ class Parser {
6 => 'heavyweapons', 6 => 'heavyweapons',
7 => 'pyro', 7 => 'pyro',
8 => 'spy', 8 => 'spy',
9 => 'engineer' 9 => 'engineer',
]; ];
/** @var RawParser */ /** @var RawParser */
@ -37,6 +38,7 @@ class Parser {
if (!is_array($data)) { if (!is_array($data)) {
throw new \InvalidArgumentException('Error parsing demo'); throw new \InvalidArgumentException('Error parsing demo');
} }
return $this->handleData($data); return $this->handleData($data);
} }
@ -50,9 +52,9 @@ class Parser {
$players = []; $players = [];
foreach ($data['rounds'] as $round) { foreach ($data['rounds'] as $round) {
if ($round['winner'] === 'red') { if ($round['winner'] === 'red') {
$red++; ++$red;
} else { } else {
$blue++; ++$blue;
} }
} }
@ -100,16 +102,18 @@ class Parser {
} }
/** /**
* Credit to https://github.com/koraktor/steam-condenser-php * Credit to https://github.com/koraktor/steam-condenser-php.
* *
* Converts a SteamID as reported by game servers to a 64bit numeric * Converts a SteamID as reported by game servers to a 64bit numeric
* SteamID as used by the Steam Community * SteamID as used by the Steam Community
* *
* @param string $steamId The SteamID string as used on servers, like * @param string $steamId The SteamID string as used on servers, like
* <var>STEAM_0:0:12345</var> * <var>STEAM_0:0:12345</var>
* @return string The converted 64bit numeric SteamID *
* @throws \InvalidArgumentException if the SteamID doesn't have the correct * @throws \InvalidArgumentException if the SteamID doesn't have the correct
* format * format
*
* @return string The converted 64bit numeric SteamID
*/ */
public function convertSteamIdToCommunityId($steamId) { public function convertSteamIdToCommunityId($steamId) {
if ($steamId === 'STEAM_ID_LAN' || $steamId === 'BOT') { if ($steamId === 'STEAM_ID_LAN' || $steamId === 'BOT') {
@ -118,10 +122,12 @@ class Parser {
if (preg_match('/^STEAM_[0-1]:[0-1]:[0-9]+$/', $steamId)) { if (preg_match('/^STEAM_[0-1]:[0-1]:[0-9]+$/', $steamId)) {
$steamParts = explode(':', substr($steamId, 8)); $steamParts = explode(':', substr($steamId, 8));
$steamId = $steamParts[0] + $steamParts[1] * 2 + 1197960265728; $steamId = $steamParts[0] + $steamParts[1] * 2 + 1197960265728;
return '7656' . $steamId; return '7656' . $steamId;
} elseif (preg_match('/^\[U:[0-1]:[0-9]+\]$/', $steamId)) { } elseif (preg_match('/^\[U:[0-1]:[0-9]+\]$/', $steamId)) {
$steamParts = explode(':', substr($steamId, 3, -1)); $steamParts = explode(':', substr($steamId, 3, -1));
$steamId = $steamParts[0] + $steamParts[1] + 1197960265727; $steamId = $steamParts[0] + $steamParts[1] + 1197960265727;
return '7656' . $steamId; return '7656' . $steamId;
} else { } else {
throw new \InvalidArgumentException("SteamID \"$steamId\" doesn't have the correct format."); throw new \InvalidArgumentException("SteamID \"$steamId\" doesn't have the correct format.");

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Demo; namespace Demostf\API\Demo;
@ -6,7 +8,7 @@ use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Exception\GuzzleException;
/** /**
* Wrapper around demo.js parser * Wrapper around demo.js parser.
* *
* Doesn't do any post-processing on the result * Doesn't do any post-processing on the result
*/ */
@ -22,10 +24,10 @@ class RawParser {
try { try {
$client = new Client(); $client = new Client();
$response = $client->post($this->parserUrl, [ $response = $client->post($this->parserUrl, [
'body' => fopen($path, 'r') 'body' => fopen($path, 'r'),
]); ]);
$result = json_decode($response->getBody()->getContents(), true); $result = json_decode($response->getBody()->getContents(), true);
if (is_null($result)) { if (null === $result) {
throw new \Exception('Failed to parse demo, unexpected result from parser'); throw new \Exception('Failed to parse demo, unexpected result from parser');
} else { } else {
return $result; return $result;

View file

@ -1,4 +1,8 @@
<?php namespace Demostf\API\Providers; <?php
declare(strict_types=1);
namespace Demostf\API\Providers;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
use RandomLib\Generator; use RandomLib\Generator;
@ -22,13 +26,14 @@ class AuthProvider extends BaseProvider {
apcu_store($token, [ apcu_store($token, [
'name' => $steamid->getNickname(), 'name' => $steamid->getNickname(),
'steamid' => $steamid->getSteamId64(), 'steamid' => $steamid->getSteamId64(),
'key' => $key 'key' => $key,
]); ]);
} }
public function getUser($token) { public function getUser($token) {
$found = true; $found = true;
$result = apcu_fetch($token, $found); $result = apcu_fetch($token, $found);
return $found ? $result : ['name' => null, 'steamid' => null, 'key' => null]; return $found ? $result : ['name' => null, 'steamid' => null, 'key' => null];
} }

View file

@ -1,4 +1,8 @@
<?php namespace Demostf\API\Providers; <?php
declare(strict_types=1);
namespace Demostf\API\Providers;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Platforms\MySqlPlatform; use Doctrine\DBAL\Platforms\MySqlPlatform;
@ -26,7 +30,7 @@ class BaseProvider {
private function dbConfig() { private function dbConfig() {
$platform = $this->connection->getDatabasePlatform(); $platform = $this->connection->getDatabasePlatform();
if ($platform instanceof MySqlPlatform) { if ($platform instanceof MySqlPlatform) {
$this->db->setIdentifierDelimiter("`"); $this->db->setIdentifierDelimiter('`');
} else { } else {
$this->db->setIdentifierDelimiter('"'); $this->db->setIdentifierDelimiter('"');
} }
@ -34,11 +38,10 @@ class BaseProvider {
$this->db->setRewrite(function ($table) { $this->db->setRewrite(function ($table) {
$rawNames = ['chat']; $rawNames = ['chat'];
$aliases = [ $aliases = [
]; ];
if (isset($aliases[$table])) { if (isset($aliases[$table])) {
return $aliases[$table]; return $aliases[$table];
} elseif (array_search($table, $rawNames) === false) { } elseif (array_search($table, $rawNames, true) === false) {
return $table . 's'; return $table . 's';
} else { } else {
return $table; return $table;

View file

@ -1,4 +1,8 @@
<?php namespace Demostf\API\Providers; <?php
declare(strict_types=1);
namespace Demostf\API\Providers;
use Demostf\API\Demo\ChatMessage; use Demostf\API\Demo\ChatMessage;
@ -10,6 +14,7 @@ class ChatProvider extends BaseProvider {
->where($query->expr()->eq('demo_id', $query->createNamedParameter($demoId, \PDO::PARAM_INT))); ->where($query->expr()->eq('demo_id', $query->createNamedParameter($demoId, \PDO::PARAM_INT)));
$result = $query->execute(); $result = $query->execute();
return array_map(function (array $row) { return array_map(function (array $row) {
return new ChatMessage( return new ChatMessage(
$row['from'], $row['from'],

View file

@ -1,4 +1,8 @@
<?php namespace Demostf\API\Providers; <?php
declare(strict_types=1);
namespace Demostf\API\Providers;
use Demostf\API\Demo\Demo; use Demostf\API\Demo\Demo;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
@ -7,6 +11,7 @@ class DemoListProvider extends BaseProvider {
public function listUploads(string $steamid, int $page, array $where = []) { public function listUploads(string $steamid, int $page, array $where = []) {
$user = $this->db->user()->where('steamid', $steamid); $user = $this->db->user()->where('steamid', $steamid);
$where['uploader'] = $user->fetch()->id; $where['uploader'] = $user->fetch()->id;
return $this->listDemos($page, $where); return $this->listDemos($page, $where);
} }
@ -31,6 +36,7 @@ class DemoListProvider extends BaseProvider {
$demos = $this->db->demo()->where('id', $demoIds) $demos = $this->db->demo()->where('id', $demoIds)
->where($where) ->where($where)
->orderBy('id', 'DESC'); ->orderBy('id', 'DESC');
return $this->formatList($demos->fetchAll()); return $this->formatList($demos->fetchAll());
} }
@ -38,6 +44,7 @@ class DemoListProvider extends BaseProvider {
* @param int $page * @param int $page
* @param array $where * @param array $where
* @param string $order * @param string $order
*
* @return Demo[] * @return Demo[]
*/ */
public function listDemos(int $page, array $where = [], $order = 'DESC') { public function listDemos(int $page, array $where = [], $order = 'DESC') {
@ -66,6 +73,7 @@ class DemoListProvider extends BaseProvider {
->setFirstResult($offset); ->setFirstResult($offset);
$demos = $query->execute()->fetchAll(\PDO::FETCH_ASSOC); $demos = $query->execute()->fetchAll(\PDO::FETCH_ASSOC);
return $this->formatList($demos); return $this->formatList($demos);
} }

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Providers; namespace Demostf\API\Providers;
@ -37,12 +39,13 @@ class DemoProvider extends BaseProvider {
'id' => $uploader['id'], 'id' => $uploader['id'],
'steamid' => $uploader['steamid'], 'steamid' => $uploader['steamid'],
'name' => $uploader['name'], 'name' => $uploader['name'],
'avatar' => $uploader['avatar'] 'avatar' => $uploader['avatar'],
])); ]));
$formattedDemo->setPlayers(array_map(function ($player) { $formattedDemo->setPlayers(array_map(function ($player) {
return DemoPlayer::fromRow($player); return DemoPlayer::fromRow($player);
}, $players)); }, $players));
} }
return $formattedDemo; return $formattedDemo;
} }
@ -76,9 +79,10 @@ class DemoProvider extends BaseProvider {
'server' => $query->createNamedParameter($demo->getServer()), 'server' => $query->createNamedParameter($demo->getServer()),
'nick' => $query->createNamedParameter($demo->getNick()), 'nick' => $query->createNamedParameter($demo->getNick()),
'"playerCount"' => $query->createNamedParameter($demo->getPlayerCount(), \PDO::PARAM_INT), '"playerCount"' => $query->createNamedParameter($demo->getPlayerCount(), \PDO::PARAM_INT),
'hash' => $query->createNamedParameter($demo->getHash()) 'hash' => $query->createNamedParameter($demo->getHash()),
]) ])
->execute(); ->execute();
return (int) $this->connection->lastInsertId(); return (int) $this->connection->lastInsertId();
} }

View file

@ -1,9 +1,14 @@
<?php namespace Demostf\API\Providers; <?php
declare(strict_types=1);
namespace Demostf\API\Providers;
class InfoProvider extends BaseProvider { class InfoProvider extends BaseProvider {
public function listMaps() { public function listMaps() {
$sql = 'SELECT DISTINCT(map), COUNT(map) AS count from demos GROUP BY map ORDER BY count DESC'; $sql = 'SELECT DISTINCT(map), COUNT(map) AS count from demos GROUP BY map ORDER BY count DESC';
$result = $this->query($sql); $result = $this->query($sql);
return $result->fetchAll(\PDO::FETCH_COLUMN); return $result->fetchAll(\PDO::FETCH_COLUMN);
} }
@ -13,7 +18,7 @@ class InfoProvider extends BaseProvider {
return [ return [
'demos' => $demoCount, 'demos' => $demoCount,
'players' => $playerCount 'players' => $playerCount,
]; ];
} }
} }

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Providers; namespace Demostf\API\Providers;
@ -15,7 +17,7 @@ class KillProvider extends BaseProvider {
'victim_id' => $query->createNamedParameter($kill->getVictimId()), 'victim_id' => $query->createNamedParameter($kill->getVictimId()),
'weapon' => $query->createNamedParameter($kill->getWeapon()), 'weapon' => $query->createNamedParameter($kill->getWeapon()),
'created_at' => 'now()', 'created_at' => 'now()',
'updated_at' => 'now()' 'updated_at' => 'now()',
]); ]);
$query->execute(); $query->execute();

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Providers; namespace Demostf\API\Providers;
@ -16,7 +18,7 @@ class PlayerProvider extends BaseProvider {
'team' => $query->createNamedParameter($player->getTeam()), 'team' => $query->createNamedParameter($player->getTeam()),
'class' => $query->createNamedParameter($player->getClass()), 'class' => $query->createNamedParameter($player->getClass()),
'created_at' => 'now()', 'created_at' => 'now()',
'updated_at' => 'now()' 'updated_at' => 'now()',
]); ]);
$query->execute(); $query->execute();

View file

@ -1,9 +1,11 @@
<?php namespace Demostf\API\Providers; <?php
declare(strict_types=1);
namespace Demostf\API\Providers;
use Demostf\API\Data\DemoPlayer;
use Demostf\API\Data\ParsedDemo; use Demostf\API\Data\ParsedDemo;
use Demostf\API\Data\Upload; use Demostf\API\Data\Upload;
use Demostf\API\Data\User;
use Demostf\API\Demo\DemoSaver; use Demostf\API\Demo\DemoSaver;
use Demostf\API\Demo\DemoStore; use Demostf\API\Demo\DemoStore;
use Demostf\API\Demo\Header; use Demostf\API\Demo\Header;

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Providers; namespace Demostf\API\Providers;
@ -31,11 +33,12 @@ class UserProvider extends BaseProvider {
'steamid' => $query->createNamedParameter($steamId->getSteamId64()), 'steamid' => $query->createNamedParameter($steamId->getSteamId64()),
'name' => $query->createNamedParameter($steamId->getNickname()), 'name' => $query->createNamedParameter($steamId->getNickname()),
'avatar' => $query->createNamedParameter($steamId->getMediumAvatarUrl()), 'avatar' => $query->createNamedParameter($steamId->getMediumAvatarUrl()),
'token' => $query->createNamedParameter($token) 'token' => $query->createNamedParameter($token),
])->add('orderBy', 'ON CONFLICT DO NOTHING')// hack to append arbitrary string to sql ])->add('orderBy', 'ON CONFLICT DO NOTHING')// hack to append arbitrary string to sql
->execute(); ->execute();
$user = $this->get($steamId->getSteamId64()); $user = $this->get($steamId->getSteamId64());
return $user ? $user->getToken() : $token; return $user ? $user->getToken() : $token;
} }
@ -46,6 +49,7 @@ class UserProvider extends BaseProvider {
->where($query->expr()->eq('steamid', $query->createNamedParameter($steamid))); ->where($query->expr()->eq('steamid', $query->createNamedParameter($steamid)));
$row = $query->execute()->fetch(); $row = $query->execute()->fetch();
return $row ? User::fromRow($row) : null; return $row ? User::fromRow($row) : null;
} }
@ -71,7 +75,7 @@ class UserProvider extends BaseProvider {
$bySteamId = $this->searchBySteamId($query); $bySteamId = $this->searchBySteamId($query);
if ($bySteamId) { if ($bySteamId) {
return [ return [
$bySteamId $bySteamId,
]; ];
} }
@ -106,7 +110,7 @@ class UserProvider extends BaseProvider {
$result[$id] = [ $result[$id] = [
'id' => $id, 'id' => $id,
'name' => $player['name'], 'name' => $player['name'],
'steamid' => $player['steamid'] 'steamid' => $player['steamid'],
]; ];
} }
} }
@ -121,6 +125,7 @@ class UserProvider extends BaseProvider {
->where($query->expr()->eq('token', $query->createNamedParameter($key))); ->where($query->expr()->eq('token', $query->createNamedParameter($key)));
$row = $query->execute()->fetch(); $row = $query->execute()->fetch();
return $row ? User::fromRow($row) : null; return $row ? User::fromRow($row) : null;
} }

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API; namespace Demostf\API;
@ -24,11 +26,13 @@ $infoController = new Controllers\InfoController($container->getInfoProvider());
Flight::route('/*', function () { Flight::route('/*', function () {
header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Origin: *');
return true; return true;
}); });
Flight::route('/auth/*', function () { Flight::route('/auth/*', function () {
session_start(); session_start();
return true; return true;
}); });

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
use Demostf\API\Container; use Demostf\API\Container;
@ -27,7 +29,7 @@ $parserUrl = getenv('PARSER_URL') ?: '';
$appRoot = getenv('APP_ROOT') ?: ''; $appRoot = getenv('APP_ROOT') ?: '';
$editKey = getenv('EDIT_SECRET') ?: ''; $editKey = getenv('EDIT_SECRET') ?: '';
$factory = new \RandomLib\Factory; $factory = new \RandomLib\Factory();
$generator = $factory->getMediumStrengthGenerator(); $generator = $factory->getMediumStrengthGenerator();
$container = new Container( $container = new Container(

View file

@ -1,3 +1,4 @@
<?php <?php
declare(strict_types=1);
require __DIR__ . '/../app.php'; require __DIR__ . '/../app.php';

View file

@ -1,3 +1,4 @@
<?php <?php
declare(strict_types=1);
require __DIR__ . '/../upload.php'; require __DIR__ . '/../upload.php';

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API; namespace Demostf\API;
@ -12,6 +14,7 @@ $uploadController = new Controllers\UploadController($container->getUploadProvid
Flight::route('/*', function () { Flight::route('/*', function () {
header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Origin: *');
return true; return true;
}); });

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Test\Data; namespace Demostf\API\Test\Data;
@ -17,7 +19,7 @@ class DemoPlayerTest extends TestCase {
'avatar' => 'asd.png', 'avatar' => 'asd.png',
'kills' => 5, 'kills' => 5,
'assists' => 3, 'assists' => 3,
'deaths' => 7 'deaths' => 7,
]; ];
$demoPlayer = DemoPlayer::fromRow($data); $demoPlayer = DemoPlayer::fromRow($data);

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Test\Demo; namespace Demostf\API\Test\Demo;
@ -56,7 +58,7 @@ class DemoSaverTest extends TestCase {
3, 3,
[ [
new ChatMessage('user1', 12, 'msg1'), new ChatMessage('user1', 12, 'msg1'),
new ChatMessage('user2', 13, 'msg2') new ChatMessage('user2', 13, 'msg2'),
], ],
[ [
new ParsedPlayer('user1', 1, '1234567', 'red', 'scout'), new ParsedPlayer('user1', 1, '1234567', 'red', 'scout'),
@ -107,7 +109,7 @@ class DemoSaverTest extends TestCase {
$this->assertEquals([ $this->assertEquals([
new ChatMessage('user1', 12, 'msg1'), new ChatMessage('user1', 12, 'msg1'),
new ChatMessage('user2', 13, 'msg2') new ChatMessage('user2', 13, 'msg2'),
], $chatProvider->getChat($demoId)); ], $chatProvider->getChat($demoId));
} }
} }

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Test\Demo; namespace Demostf\API\Test\Demo;

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Test\Demo; namespace Demostf\API\Test\Demo;
@ -44,7 +46,7 @@ class HeaderParserTest extends TestCase {
*/ */
public function testNonDemoShort() { public function testNonDemoShort() {
$parser = new HeaderParser(); $parser = new HeaderParser();
$parser->parseString("short"); $parser->parseString('short');
} }
/** /**

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Test\Demo; namespace Demostf\API\Test\Demo;
@ -21,6 +23,7 @@ class ParserTest extends TestCase {
->method('parse') ->method('parse')
->will($this->returnCallback(function ($path) { ->will($this->returnCallback(function ($path) {
$jsonPath = str_replace('.dem', '-raw.json', $path); $jsonPath = str_replace('.dem', '-raw.json', $path);
return json_decode(file_get_contents($jsonPath), true); return json_decode(file_get_contents($jsonPath), true);
})); }));
} }

View file

@ -1,4 +1,6 @@
<?php declare(strict_types = 1); <?php
declare(strict_types=1);
namespace Demostf\API\Test\Providers; namespace Demostf\API\Test\Providers;

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Test\Providers; namespace Demostf\API\Test\Providers;

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Test\Providers; namespace Demostf\API\Test\Providers;
@ -149,11 +151,13 @@ class DemoProviderTest extends TestCase {
private function addPlayer(int $demoId, int $demoUserId, int $userId, string $team, string $class): int { private function addPlayer(int $demoId, int $demoUserId, int $userId, string $team, string $class): int {
$player = new Player(0, $demoId, $demoUserId, $userId, 'user_' . $userId, $team, $class); $player = new Player(0, $demoId, $demoUserId, $userId, 'user_' . $userId, $team, $class);
return $this->playerProvider->store($player); return $this->playerProvider->store($player);
} }
private function addKill(int $demoId, int $attackerId, int $assisterId, int $victimId, string $weapon): int { private function addKill(int $demoId, int $attackerId, int $assisterId, int $victimId, string $weapon): int {
$kill = new Kill(0, $demoId, $attackerId, $assisterId, $victimId, $weapon); $kill = new Kill(0, $demoId, $attackerId, $assisterId, $victimId, $weapon);
return $this->killProvider->store($kill); return $this->killProvider->store($kill);
} }

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Test\Providers; namespace Demostf\API\Test\Providers;
@ -49,6 +51,7 @@ class UploadProviderTest extends TestCase {
->method('parse') ->method('parse')
->will($this->returnCallback(function ($path) { ->will($this->returnCallback(function ($path) {
$jsonPath = str_replace('.dem', '-raw.json', $path); $jsonPath = str_replace('.dem', '-raw.json', $path);
return json_decode(file_get_contents($jsonPath), true); return json_decode(file_get_contents($jsonPath), true);
})); }));
@ -290,7 +293,6 @@ class UploadProviderTest extends TestCase {
$this->saveSteamId('[U:1:143626373]', 'Pendulum'); $this->saveSteamId('[U:1:143626373]', 'Pendulum');
$this->saveSteamId('[U:1:30220936]', 'Jedi'); $this->saveSteamId('[U:1:30220936]', 'Jedi');
$result = $this->uploadProvider->upload($token, 'RED', 'BLU', 'foodemo', $this->tmpDir . '/foo.dem'); $result = $this->uploadProvider->upload($token, 'RED', 'BLU', 'foodemo', $this->tmpDir . '/foo.dem');
$this->assertStringStartsWith('STV available at: http://example.com/', $result); $this->assertStringStartsWith('STV available at: http://example.com/', $result);

View file

@ -1,4 +1,6 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
namespace Demostf\API\Test\Providers; namespace Demostf\API\Test\Providers;
@ -72,7 +74,6 @@ class UserProviderTest extends TestCase {
$user = $this->provider->get($this->steamId->getSteamId64()); $user = $this->provider->get($this->steamId->getSteamId64());
$this->assertEquals($user->getId(), $id); $this->assertEquals($user->getId(), $id);
} }
} }

View file

@ -1,4 +1,8 @@
<?php namespace Demostf\API\Test; <?php
declare(strict_types=1);
namespace Demostf\API\Test;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\DriverManager;
@ -22,6 +26,7 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase {
} }
$this->database = DriverManager::getConnection($connectionParams); $this->database = DriverManager::getConnection($connectionParams);
} }
return $this->database; return $this->database;
} }
@ -49,7 +54,8 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase {
} }
protected function getRandomGenerator() { protected function getRandomGenerator() {
$factory = new \RandomLib\Factory; $factory = new \RandomLib\Factory();
return $factory->getMediumStrengthGenerator(); return $factory->getMediumStrengthGenerator();
} }
@ -60,6 +66,7 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase {
$steamId->imageUrl = 'foo'; $steamId->imageUrl = 'foo';
}, null, $steamId); }, null, $steamId);
$closure($steamId); $closure($steamId);
return $steamId; return $steamId;
} }
} }

View file

@ -1 +1,4 @@
<?php require_once __DIR__ . '/../src/init.php'; <?php
declare(strict_types=1);
require_once __DIR__ . '/../src/init.php';

View file

@ -1,17 +1,19 @@
<?php declare(strict_types=1); <?php
declare(strict_types=1);
$_SERVER['SCRIPT_NAME'] = ''; $_SERVER['SCRIPT_NAME'] = '';
if ($_SERVER["REQUEST_URI"] === '/upload') { if ($_SERVER['REQUEST_URI'] === '/upload') {
require __DIR__ . '/../src/public/upload.php'; require __DIR__ . '/../src/public/upload.php';
} elseif ($_SERVER["REQUEST_URI"] === '/reset') { } elseif ($_SERVER['REQUEST_URI'] === '/reset') {
// allow the api tests to reset the database // allow the api tests to reset the database
/** @var \Demostf\API\Container $container */ /** @var \Demostf\API\Container $container */
$container = require __DIR__ . '/../src/init.php'; $container = require __DIR__ . '/../src/init.php';
$connection = $container->getConnection(); $connection = $container->getConnection();
clearDatabase($connection); clearDatabase($connection);
} elseif ($_SERVER["REQUEST_URI"] === '/testuser') { } elseif ($_SERVER['REQUEST_URI'] === '/testuser') {
// allow the api tests to create a test user // allow the api tests to create a test user
/** @var \Demostf\API\Container $container */ /** @var \Demostf\API\Container $container */
$container = require __DIR__ . '/../src/init.php'; $container = require __DIR__ . '/../src/init.php';
@ -23,7 +25,7 @@ if ($_SERVER["REQUEST_URI"] === '/upload') {
'steamid' => $query->createNamedParameter('steamid1'), 'steamid' => $query->createNamedParameter('steamid1'),
'name' => $query->createNamedParameter('nickname1'), 'name' => $query->createNamedParameter('nickname1'),
'avatar' => $query->createNamedParameter('avatar1'), 'avatar' => $query->createNamedParameter('avatar1'),
'token' => $query->createNamedParameter('key1') 'token' => $query->createNamedParameter('key1'),
])->add('orderBy', 'ON CONFLICT DO NOTHING')// hack to append arbitrary string to sql ])->add('orderBy', 'ON CONFLICT DO NOTHING')// hack to append arbitrary string to sql
->execute(); ->execute();
} else { } else {